@lionrapid/core 0.5.0 → 0.6.0
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/base/event-emitter.d.ts.map +1 -1
- package/dist/base/event-emitter.js +2 -1
- package/dist/base/event-emitter.js.map +1 -1
- package/dist/browser/attribute-extractor.d.ts.map +1 -1
- package/dist/browser/attribute-extractor.js +2 -1
- package/dist/browser/attribute-extractor.js.map +1 -1
- package/dist/browser/auto-init.d.ts +64 -0
- package/dist/browser/auto-init.d.ts.map +1 -1
- package/dist/browser/auto-init.js +171 -59
- package/dist/browser/auto-init.js.map +1 -1
- package/dist/browser/block-extractor.d.ts.map +1 -1
- package/dist/browser/block-extractor.js +3 -1
- package/dist/browser/block-extractor.js.map +1 -1
- package/dist/browser/editor/editor-api.d.ts +50 -6
- package/dist/browser/editor/editor-api.d.ts.map +1 -1
- package/dist/browser/editor/editor-api.js +121 -19
- package/dist/browser/editor/editor-api.js.map +1 -1
- package/dist/browser/editor/editor-init.js +4 -1
- package/dist/browser/editor/editor-init.js.map +1 -1
- package/dist/browser/editor/sidebar.d.ts +4 -3
- package/dist/browser/editor/sidebar.d.ts.map +1 -1
- package/dist/browser/editor/sidebar.js +93 -27
- package/dist/browser/editor/sidebar.js.map +1 -1
- package/dist/browser/editor/snapshot-viewer.d.ts.map +1 -1
- package/dist/browser/editor/snapshot-viewer.js +32 -3
- package/dist/browser/editor/snapshot-viewer.js.map +1 -1
- package/dist/browser/lionrapid.auto.dev.js +424 -147
- package/dist/browser/lionrapid.auto.dev.js.map +4 -4
- package/dist/browser/lionrapid.auto.js +424 -147
- package/dist/browser/lionrapid.auto.js.map +4 -4
- package/dist/browser/lionrapid.auto.min.js +4 -3
- package/dist/browser/lionrapid.auto.min.js.map +4 -4
- package/dist/browser/lionrapid.editor.js +1467 -1115
- package/dist/browser/lionrapid.editor.js.map +4 -4
- package/dist/browser/lionrapid.editor.min.js +4 -3
- package/dist/browser/lionrapid.editor.min.js.map +4 -4
- package/dist/browser/lionrapid.esm.js +584 -101
- package/dist/browser/lionrapid.esm.js.map +4 -4
- package/dist/browser/lionrapid.esm.min.js +3 -2
- package/dist/browser/lionrapid.esm.min.js.map +4 -4
- package/dist/browser/lionrapid.iife.dev.js +584 -101
- package/dist/browser/lionrapid.iife.dev.js.map +4 -4
- package/dist/browser/lionrapid.iife.js +584 -101
- package/dist/browser/lionrapid.iife.js.map +4 -4
- package/dist/browser/lionrapid.iife.min.js +3 -2
- package/dist/browser/lionrapid.iife.min.js.map +4 -4
- package/dist/browser/lionrapid.umd.js +584 -101
- package/dist/browser/lionrapid.umd.js.map +4 -4
- package/dist/browser/lionrapid.umd.min.js +3 -2
- package/dist/browser/lionrapid.umd.min.js.map +4 -4
- package/dist/browser/sanitizer.d.ts +37 -0
- package/dist/browser/sanitizer.d.ts.map +1 -0
- package/dist/browser/sanitizer.js +93 -0
- package/dist/browser/sanitizer.js.map +1 -0
- package/dist/builder.d.ts +8 -0
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +33 -5
- package/dist/builder.js.map +1 -1
- package/dist/config/lionrapid.config.d.ts +0 -1
- package/dist/config/lionrapid.config.d.ts.map +1 -1
- package/dist/config/repository.config.d.ts +2 -2
- package/dist/config/repository.config.d.ts.map +1 -1
- package/dist/content/index.d.ts +3 -0
- package/dist/content/index.d.ts.map +1 -1
- package/dist/content/index.js +5 -0
- package/dist/content/index.js.map +1 -1
- package/dist/content/sanitizer/HTMLSanitizer.d.ts +105 -0
- package/dist/content/sanitizer/HTMLSanitizer.d.ts.map +1 -0
- package/dist/content/sanitizer/HTMLSanitizer.js +257 -0
- package/dist/content/sanitizer/HTMLSanitizer.js.map +1 -0
- package/dist/content/serializer/HTMLSerializer.d.ts +6 -2
- package/dist/content/serializer/HTMLSerializer.d.ts.map +1 -1
- package/dist/content/serializer/HTMLSerializer.js +16 -8
- package/dist/content/serializer/HTMLSerializer.js.map +1 -1
- package/dist/content/splitter/BlockSplitter.d.ts +66 -0
- package/dist/content/splitter/BlockSplitter.d.ts.map +1 -0
- package/dist/content/splitter/BlockSplitter.js +219 -0
- package/dist/content/splitter/BlockSplitter.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -1
- package/dist/lionRapid.d.ts +1 -2
- package/dist/lionRapid.d.ts.map +1 -1
- package/dist/lionRapid.js +5 -7
- package/dist/lionRapid.js.map +1 -1
- package/dist/repositories/network-repository.d.ts +30 -8
- package/dist/repositories/network-repository.d.ts.map +1 -1
- package/dist/repositories/network-repository.js +88 -74
- package/dist/repositories/network-repository.js.map +1 -1
- package/dist/types/lionRapid.types.d.ts +2 -0
- package/dist/types/lionRapid.types.d.ts.map +1 -1
- package/dist/types/translation.types.d.ts +0 -3
- package/dist/types/translation.types.d.ts.map +1 -1
- package/dist/utils/context-utils.d.ts +1 -2
- package/dist/utils/context-utils.d.ts.map +1 -1
- package/dist/utils/context-utils.js +3 -6
- package/dist/utils/context-utils.js.map +1 -1
- package/dist/utils/locale.d.ts +57 -0
- package/dist/utils/locale.d.ts.map +1 -0
- package/dist/utils/locale.js +116 -0
- package/dist/utils/locale.js.map +1 -0
- package/dist/utils/translation-flow.d.ts +1 -1
- package/dist/utils/translation-flow.d.ts.map +1 -1
- package/dist/utils/translation-flow.js +2 -3
- package/dist/utils/translation-flow.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM-tree sanitizer — the live-tree companion to the pure-string
|
|
3
|
+
* `content/sanitizer/HTMLSanitizer`. Used where a whole fragment of
|
|
4
|
+
* untrusted HTML becomes live DOM: today the snapshot viewer, which mounts
|
|
5
|
+
* server-fetched snapshot HTML in the editor realm (PM session JWT).
|
|
6
|
+
*
|
|
7
|
+
* POLICY NOTE — this deliberately diverges from the inline `SAFE_TAGS`
|
|
8
|
+
* allowlist (see PHASES.md Phase 4): a snapshot is a full captured page, so
|
|
9
|
+
* structural elements (`div`/`p`/`h1`/`nav`/`table`/…) must survive for the
|
|
10
|
+
* page to render at all. What is enforced instead:
|
|
11
|
+
* - executable/embedding elements are REMOVED outright
|
|
12
|
+
* - every `on*` handler attribute (and `srcdoc`) is dropped
|
|
13
|
+
* - URL-bearing attributes must pass `sanitizeUrl`
|
|
14
|
+
* - inline `style` keeps any property (layout fidelity) but value-level
|
|
15
|
+
* dangers are dropped via `sanitizeCssDeclarations`
|
|
16
|
+
*
|
|
17
|
+
* CONTINUOUS DEVELOPMENT: like SAFE_STYLE_PROPS, these sets grow (or
|
|
18
|
+
* tighten) deliberately as real snapshots surface gaps — extend REMOVE_TAGS
|
|
19
|
+
* rather than trusting a new embedding surface, add hostile cases to
|
|
20
|
+
* sanitize-element.test.ts, and keep the WP/edge ports in sync if they ever
|
|
21
|
+
* grow a snapshot feature.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Sanitize a live element tree in place (root included).
|
|
25
|
+
*/
|
|
26
|
+
export declare function sanitizeElement(root: Element): void;
|
|
27
|
+
/**
|
|
28
|
+
* Best-effort sanitization of a copied `<style>` sheet's text: strips
|
|
29
|
+
* `@import` (arbitrary stylesheet pull-in), neutralizes `url(...)`
|
|
30
|
+
* references that resolve cross-origin (exfil beacons in a tampered
|
|
31
|
+
* snapshot), and defuses legacy `expression(`. Same-origin, relative, and
|
|
32
|
+
* `data:` URLs are kept so the snapshot still renders its images/fonts.
|
|
33
|
+
* The primary defenses are element removal + attribute scrubbing in
|
|
34
|
+
* `sanitizeElement`; this closes the stylesheet side channel.
|
|
35
|
+
*/
|
|
36
|
+
export declare function sanitizeStyleSheetText(css: string, baseHref: string): string;
|
|
37
|
+
//# sourceMappingURL=sanitizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitizer.d.ts","sourceRoot":"","sources":["../../src/browser/sanitizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAkBH;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CA4BnD;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAgB5E"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM-tree sanitizer — the live-tree companion to the pure-string
|
|
3
|
+
* `content/sanitizer/HTMLSanitizer`. Used where a whole fragment of
|
|
4
|
+
* untrusted HTML becomes live DOM: today the snapshot viewer, which mounts
|
|
5
|
+
* server-fetched snapshot HTML in the editor realm (PM session JWT).
|
|
6
|
+
*
|
|
7
|
+
* POLICY NOTE — this deliberately diverges from the inline `SAFE_TAGS`
|
|
8
|
+
* allowlist (see PHASES.md Phase 4): a snapshot is a full captured page, so
|
|
9
|
+
* structural elements (`div`/`p`/`h1`/`nav`/`table`/…) must survive for the
|
|
10
|
+
* page to render at all. What is enforced instead:
|
|
11
|
+
* - executable/embedding elements are REMOVED outright
|
|
12
|
+
* - every `on*` handler attribute (and `srcdoc`) is dropped
|
|
13
|
+
* - URL-bearing attributes must pass `sanitizeUrl`
|
|
14
|
+
* - inline `style` keeps any property (layout fidelity) but value-level
|
|
15
|
+
* dangers are dropped via `sanitizeCssDeclarations`
|
|
16
|
+
*
|
|
17
|
+
* CONTINUOUS DEVELOPMENT: like SAFE_STYLE_PROPS, these sets grow (or
|
|
18
|
+
* tighten) deliberately as real snapshots surface gaps — extend REMOVE_TAGS
|
|
19
|
+
* rather than trusting a new embedding surface, add hostile cases to
|
|
20
|
+
* sanitize-element.test.ts, and keep the WP/edge ports in sync if they ever
|
|
21
|
+
* grow a snapshot feature.
|
|
22
|
+
*/
|
|
23
|
+
import { sanitizeUrl, sanitizeCssDeclarations, } from '../content/sanitizer/HTMLSanitizer.js';
|
|
24
|
+
/** Elements that can execute, embed, or retarget — removed with their subtree. */
|
|
25
|
+
const REMOVE_TAGS = new Set([
|
|
26
|
+
'script', 'iframe', 'frame', 'frameset', 'object', 'embed', 'applet',
|
|
27
|
+
'base', 'meta', 'link', 'template', 'portal',
|
|
28
|
+
]);
|
|
29
|
+
/** Attributes whose values navigate or fetch — must pass sanitizeUrl. */
|
|
30
|
+
const URL_ATTRS = new Set([
|
|
31
|
+
'href', 'src', 'action', 'formaction', 'poster', 'data', 'xlink:href',
|
|
32
|
+
]);
|
|
33
|
+
/**
|
|
34
|
+
* Sanitize a live element tree in place (root included).
|
|
35
|
+
*/
|
|
36
|
+
export function sanitizeElement(root) {
|
|
37
|
+
// Snapshot the list first — removals during iteration are safe this way.
|
|
38
|
+
const all = [root, ...Array.from(root.querySelectorAll('*'))];
|
|
39
|
+
for (const el of all) {
|
|
40
|
+
const tag = el.tagName.toLowerCase();
|
|
41
|
+
if (REMOVE_TAGS.has(tag)) {
|
|
42
|
+
el.remove();
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
for (const name of el.getAttributeNames()) {
|
|
46
|
+
const lower = name.toLowerCase();
|
|
47
|
+
if (lower.startsWith('on') || lower === 'srcdoc') {
|
|
48
|
+
el.removeAttribute(name);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (URL_ATTRS.has(lower)) {
|
|
52
|
+
if (sanitizeUrl(el.getAttribute(name) ?? '') === null) {
|
|
53
|
+
el.removeAttribute(name);
|
|
54
|
+
}
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (lower === 'style') {
|
|
58
|
+
const clean = sanitizeCssDeclarations(el.getAttribute(name) ?? '');
|
|
59
|
+
if (clean === null)
|
|
60
|
+
el.removeAttribute(name);
|
|
61
|
+
else
|
|
62
|
+
el.setAttribute(name, clean);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Best-effort sanitization of a copied `<style>` sheet's text: strips
|
|
69
|
+
* `@import` (arbitrary stylesheet pull-in), neutralizes `url(...)`
|
|
70
|
+
* references that resolve cross-origin (exfil beacons in a tampered
|
|
71
|
+
* snapshot), and defuses legacy `expression(`. Same-origin, relative, and
|
|
72
|
+
* `data:` URLs are kept so the snapshot still renders its images/fonts.
|
|
73
|
+
* The primary defenses are element removal + attribute scrubbing in
|
|
74
|
+
* `sanitizeElement`; this closes the stylesheet side channel.
|
|
75
|
+
*/
|
|
76
|
+
export function sanitizeStyleSheetText(css, baseHref) {
|
|
77
|
+
let out = css.replace(/@import[^;]*(;|$)/gi, '');
|
|
78
|
+
out = out.replace(/url\(\s*(['"]?)([^'")]*)\1\s*\)/gi, (full, _quote, target) => {
|
|
79
|
+
try {
|
|
80
|
+
const resolved = new URL(target, baseHref);
|
|
81
|
+
if (resolved.protocol === 'data:')
|
|
82
|
+
return full;
|
|
83
|
+
if (resolved.origin === new URL(baseHref).origin)
|
|
84
|
+
return full;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
/* unparseable target → neutralize */
|
|
88
|
+
}
|
|
89
|
+
return 'url("")';
|
|
90
|
+
});
|
|
91
|
+
return out.replace(/expression\s*\(/gi, 'blocked(');
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=sanitizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sanitizer.js","sourceRoot":"","sources":["../../src/browser/sanitizer.ts"],"names":[],"mappings":"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"}
|
package/dist/builder.d.ts
CHANGED
|
@@ -6,6 +6,14 @@ import type { IEmbeddedPlugin, IPlugin } from './interfaces/plugin.interface.js'
|
|
|
6
6
|
import { IAsyncRepository, ISyncRepository } from './interfaces/repository.interface.js';
|
|
7
7
|
import { LionRapidCore } from './lionRapid.js';
|
|
8
8
|
import { type StaticBundle } from './repositories/static-repository.js';
|
|
9
|
+
/**
|
|
10
|
+
* True when a preload failure deserves a loud console diagnostic: network or
|
|
11
|
+
* server trouble the integrator should hear about. 404 (empty project) and
|
|
12
|
+
* 423 (content still being prepared) are routine states, not failures.
|
|
13
|
+
* The internal logger is compiled out of production bundles, so genuine
|
|
14
|
+
* failures must reach console.warn explicitly.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isLoudPreloadFailure(error: unknown): boolean;
|
|
9
17
|
export declare class LionRapidBuilder {
|
|
10
18
|
private config;
|
|
11
19
|
private plugins;
|
package/dist/builder.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAIxE,OAAO,KAAK,EACV,eAAe,EACf,OAAO,EACR,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,gBAAgB,EAChB,eAAe,EAChB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAIxE,OAAO,KAAK,EACV,eAAe,EACf,OAAO,EACR,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,gBAAgB,EAChB,eAAe,EAChB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAK/C,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,qCAAqC,CAAC;AAI7C;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAK5D;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,iBAAiB,CAA0B;IACnD,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,SAAS,CAAwC;gBAE7C,MAAM,EAAE,mBAAmB;IAOvC,MAAM,CAAC,IAAI,CAAC,MAAM,GAAE,mBAAwB,GAAG,gBAAgB;IAI/D,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,UAAU;IAKlB,GAAG,CACD,QAAQ,EAAE,OAAO,GAAG,eAAe,GAAG,eAAe,GAAG,gBAAgB,GACvE,gBAAgB;IAkBnB;;;;;OAKG;IACH,eAAe,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,SAAM,GAAG,gBAAgB;IAIjE,KAAK,IAAI,OAAO,CAAC,aAAa,CAAC;YAsGvB,iBAAiB;CA8DhC"}
|
package/dist/builder.js
CHANGED
|
@@ -5,9 +5,21 @@ import { EventEmitter } from './base/event-emitter.js';
|
|
|
5
5
|
import { HandlerChain } from './handlers/handler-chain.js';
|
|
6
6
|
import { AsyncHandler, NetworkHandler, SyncHandler } from './handlers/index.js';
|
|
7
7
|
import { LionRapidCore } from './lionRapid.js';
|
|
8
|
+
import { TranslationLockedError, TranslationNotFoundError, } from './errors/translation-errors.js';
|
|
8
9
|
import { StaticRepository, } from './repositories/static-repository.js';
|
|
9
10
|
import { MissingTranslationQueue } from './sync/missing-translation-queue.js';
|
|
10
11
|
import { logger } from './utils/logger.js';
|
|
12
|
+
/**
|
|
13
|
+
* True when a preload failure deserves a loud console diagnostic: network or
|
|
14
|
+
* server trouble the integrator should hear about. 404 (empty project) and
|
|
15
|
+
* 423 (content still being prepared) are routine states, not failures.
|
|
16
|
+
* The internal logger is compiled out of production bundles, so genuine
|
|
17
|
+
* failures must reach console.warn explicitly.
|
|
18
|
+
*/
|
|
19
|
+
export function isLoudPreloadFailure(error) {
|
|
20
|
+
return !(error instanceof TranslationNotFoundError ||
|
|
21
|
+
error instanceof TranslationLockedError);
|
|
22
|
+
}
|
|
11
23
|
export class LionRapidBuilder {
|
|
12
24
|
config;
|
|
13
25
|
plugins = [];
|
|
@@ -18,7 +30,6 @@ export class LionRapidBuilder {
|
|
|
18
30
|
constructor(config) {
|
|
19
31
|
this.config = {
|
|
20
32
|
defaultLocale: config.defaultLocale || 'en',
|
|
21
|
-
fallbackLocale: config.fallbackLocale || 'en',
|
|
22
33
|
namespace: config.namespace || 'app',
|
|
23
34
|
};
|
|
24
35
|
}
|
|
@@ -125,7 +136,7 @@ export class LionRapidBuilder {
|
|
|
125
136
|
}
|
|
126
137
|
logger.debug('Handler chain constructed');
|
|
127
138
|
// Create facade
|
|
128
|
-
const facade = new LionRapidCore(eventEmitter, handlerChain, this.config.defaultLocale, this.config.
|
|
139
|
+
const facade = new LionRapidCore(eventEmitter, handlerChain, this.config.defaultLocale, this.config.namespace);
|
|
129
140
|
// Initialize plugins and add their handlers
|
|
130
141
|
for (const plugin of this.plugins) {
|
|
131
142
|
buildBus.use('plugin');
|
|
@@ -155,21 +166,38 @@ export class LionRapidBuilder {
|
|
|
155
166
|
logger.debug('Preload targets', {
|
|
156
167
|
namespaces: eagerPreloads.map(c => `${c.locale}:${c.namespace}`),
|
|
157
168
|
});
|
|
169
|
+
let warnedLoudly = false;
|
|
170
|
+
const warnLoudlyOnce = (namespaceKey, error) => {
|
|
171
|
+
if (!isLoudPreloadFailure(error) || warnedLoudly)
|
|
172
|
+
return;
|
|
173
|
+
warnedLoudly = true;
|
|
174
|
+
// eslint-disable-next-line no-console
|
|
175
|
+
console.warn(`[LionRapid] Could not load translations for ${namespaceKey} — the ` +
|
|
176
|
+
'page stays untranslated until the server is reachable.', error);
|
|
177
|
+
};
|
|
158
178
|
const promises = eagerPreloads.map(async (preloadConfig) => {
|
|
179
|
+
const namespaceKey = `${preloadConfig.locale}:${preloadConfig.namespace}`;
|
|
159
180
|
try {
|
|
160
181
|
const result = await networkHandler.loadNamespace(preloadConfig.locale, preloadConfig.namespace);
|
|
161
182
|
if (result && result.data && result.status === 200) {
|
|
162
183
|
const context = {
|
|
163
184
|
locale: preloadConfig.locale,
|
|
164
185
|
namespace: preloadConfig.namespace,
|
|
165
|
-
fallbackLocale: this.config.fallbackLocale,
|
|
166
186
|
};
|
|
167
187
|
await handlerChain.saveNamespaceToHandlers(result.data, context);
|
|
168
|
-
logger.debug(`Preloaded: ${
|
|
188
|
+
logger.debug(`Preloaded: ${namespaceKey}`);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
// loadNamespace never throws — failures come back as a fallback
|
|
192
|
+
// result with the error attached (status 0 = network/transport).
|
|
193
|
+
if (result?.error) {
|
|
194
|
+
warnLoudlyOnce(namespaceKey, result.error);
|
|
195
|
+
logger.warn(`Preload failed: ${namespaceKey}`, result.error);
|
|
169
196
|
}
|
|
170
197
|
}
|
|
171
198
|
catch (error) {
|
|
172
|
-
|
|
199
|
+
warnLoudlyOnce(namespaceKey, error);
|
|
200
|
+
logger.warn(`Preload failed: ${namespaceKey}`, error);
|
|
173
201
|
}
|
|
174
202
|
});
|
|
175
203
|
await Promise.allSettled(promises);
|
package/dist/builder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAShF,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EACL,gBAAgB,GAEjB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,MAAM,OAAO,gBAAgB;IACnB,MAAM,CAAsB;IAC5B,OAAO,GAAc,EAAE,CAAC;IACxB,gBAAgB,GAAsB,EAAE,CAAC;IACzC,iBAAiB,GAAuB,EAAE,CAAC;IAC3C,YAAY,GAAuB,EAAE,CAAC;IACtC,SAAS,GAAmC,IAAI,CAAC;IAEzD,YAAY,MAA2B;QACrC,IAAI,CAAC,MAAM,GAAG;YACZ,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,IAAI;YAC3C,
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../src/builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lionrapid.config.d.ts","sourceRoot":"","sources":["../../src/config/lionrapid.config.ts"],"names":[],"mappings":"AACA;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,
|
|
1
|
+
{"version":3,"file":"lionrapid.config.d.ts","sourceRoot":"","sources":["../../src/config/lionrapid.config.ts"],"names":[],"mappings":"AACA;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,SAAS,CAAC,EAAE,OAAO,CAAC;IAGpB,UAAU,CAAC,EAAE,MAAM,CAAC;IAGpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC"}
|
|
@@ -41,9 +41,9 @@ export interface SyncMissingConfig {
|
|
|
41
41
|
/** Enable automatic syncing of missing translations */
|
|
42
42
|
enabled: boolean;
|
|
43
43
|
/** Debounce delay in milliseconds before syncing (default: 500) */
|
|
44
|
-
debounceMs
|
|
44
|
+
debounceMs?: number;
|
|
45
45
|
/** Maximum batch size before forcing immediate flush (default: 50) */
|
|
46
|
-
batchSize
|
|
46
|
+
batchSize?: number;
|
|
47
47
|
}
|
|
48
48
|
/**
|
|
49
49
|
* Network Repository endpoint configuration
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.config.d.ts","sourceRoot":"","sources":["../../src/config/repository.config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AASH;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE;QACR,8CAA8C;QAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,4CAA4C;QAC5C,GAAG,CAAC,EAAE,MAAM,CAAC;QAEb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAGlB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,OAAO,EAAE,OAAO,CAAC;IACjB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"repository.config.d.ts","sourceRoot":"","sources":["../../src/config/repository.config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AASH;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE;QACR,8CAA8C;QAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,4CAA4C;QAC5C,GAAG,CAAC,EAAE,MAAM,CAAC;QAEb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAGlB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,OAAO,EAAE,OAAO,CAAC;IACjB,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gGAAgG;IAChG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wFAAwF;IACxF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE;QAER,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACjC,MAAM,CAAC,EAAE,MAAM,CAAC;QAGhB,SAAS,CAAC,EAAE,gBAAgB,CAAC;QAG7B,iBAAiB,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAG7C,WAAW,CAAC,EAAE,iBAAiB,CAAC;QAGhC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;CACH"}
|
package/dist/content/index.d.ts
CHANGED
|
@@ -14,4 +14,7 @@ export { HTMLSerializer } from './serializer/HTMLSerializer.js';
|
|
|
14
14
|
export type { IValidator, ValidationResult, ValidationError, ValidationWarning, ValidationErrorCode, ValidationWarningCode, } from './validator/IValidator.js';
|
|
15
15
|
export { ContentValidator } from './validator/ContentValidator.js';
|
|
16
16
|
export { VOID_TAGS, serializeOpeningTag, extractTagName, readRawStyle, } from './canonical-tag.js';
|
|
17
|
+
export { SAFE_TAGS, SAFE_ATTRS, SAFE_STYLE_PROPS, escapeHtml, sanitizeUrl, sanitizeStyle, sanitizeOpeningTag, sanitizeContentUnit, } from './sanitizer/HTMLSanitizer.js';
|
|
18
|
+
export type { HtmlBlock, SplitBlocksResult } from './splitter/BlockSplitter.js';
|
|
19
|
+
export { splitBlocks, replaceBlockInners } from './splitter/BlockSplitter.js';
|
|
17
20
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,YAAY,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGxD,YAAY,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAGhE,YAAY,EACV,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAInE,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,cAAc,EACd,YAAY,GACb,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,YAAY,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAGxD,YAAY,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAGhE,YAAY,EACV,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAInE,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,cAAc,EACd,YAAY,GACb,MAAM,oBAAoB,CAAC;AAK5B,OAAO,EACL,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAItC,YAAY,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC"}
|
package/dist/content/index.js
CHANGED
|
@@ -12,4 +12,9 @@ export { ContentValidator } from './validator/ContentValidator.js';
|
|
|
12
12
|
// Canonical raw-tag helpers — used by all parsers/serializers (core, edge,
|
|
13
13
|
// react, php) so they produce byte-identical output for the same source.
|
|
14
14
|
export { VOID_TAGS, serializeOpeningTag, extractTagName, readRawStyle, } from './canonical-tag.js';
|
|
15
|
+
// Shared allowlist HTML sanitizer — the single implementation every
|
|
16
|
+
// innerHTML sink (core, react <Trans>, WP TS) must route through; the WP
|
|
17
|
+
// PHP port mirrors SAFE_TAGS/SAFE_ATTRS.
|
|
18
|
+
export { SAFE_TAGS, SAFE_ATTRS, SAFE_STYLE_PROPS, escapeHtml, sanitizeUrl, sanitizeStyle, sanitizeOpeningTag, sanitizeContentUnit, } from './sanitizer/HTMLSanitizer.js';
|
|
19
|
+
export { splitBlocks, replaceBlockInners } from './splitter/BlockSplitter.js';
|
|
15
20
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIxD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAWhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnE,2EAA2E;AAC3E,yEAAyE;AACzE,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,cAAc,EACd,YAAY,GACb,MAAM,oBAAoB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/content/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAIxD,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAWhE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnE,2EAA2E;AAC3E,yEAAyE;AACzE,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,cAAc,EACd,YAAY,GACb,MAAM,oBAAoB,CAAC;AAE5B,oEAAoE;AACpE,yEAAyE;AACzE,yCAAyC;AACzC,OAAO,EACL,SAAS,EACT,UAAU,EACV,gBAAgB,EAChB,UAAU,EACV,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,8BAA8B,CAAC;AAKtC,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared allowlist HTML sanitizer — pure string functions, Node-safe (no DOM).
|
|
3
|
+
*
|
|
4
|
+
* One implementation for every sink that turns translation data into HTML:
|
|
5
|
+
* core's HTMLSerializer/auto-translator, the editor text sinks, the snapshot
|
|
6
|
+
* viewer, react `<Trans>`, and WordPress TS. The WordPress PHP port must
|
|
7
|
+
* mirror `SAFE_TAGS`/`SAFE_ATTRS` exactly (see improvement-plan §4 item 2).
|
|
8
|
+
*
|
|
9
|
+
* Threat model: translation values (and their `raw:` styles) come from the
|
|
10
|
+
* server/KV and may be attacker-controlled — they are NOT guaranteed to be in
|
|
11
|
+
* canonical form. Everything here is allowlist-based: unknown tags are
|
|
12
|
+
* rejected, unknown attributes dropped, URL schemes checked after entity
|
|
13
|
+
* decoding.
|
|
14
|
+
*
|
|
15
|
+
* @module content/sanitizer/HTMLSanitizer
|
|
16
|
+
*/
|
|
17
|
+
import type { ContentUnit } from '../types.js';
|
|
18
|
+
/**
|
|
19
|
+
* Inline formatting elements allowed inside translated content. Block
|
|
20
|
+
* structure lives outside ContentUnit (block-level pipeline), so anything
|
|
21
|
+
* that isn't inline text formatting is rejected outright.
|
|
22
|
+
*/
|
|
23
|
+
export declare const SAFE_TAGS: Set<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Flat attribute allowlist (plus `data-*`/`aria-*` prefixes, handled in
|
|
26
|
+
* `sanitizeOpeningTag`). Kept flat — not per-tag — so the PHP mirror stays
|
|
27
|
+
* trivial; an allowed attribute on the wrong tag is inert.
|
|
28
|
+
*/
|
|
29
|
+
export declare const SAFE_ATTRS: Set<string>;
|
|
30
|
+
/**
|
|
31
|
+
* CSS properties allowed through an inline `style` attribute.
|
|
32
|
+
*
|
|
33
|
+
* RISK NOTE — why `style` never passes through verbatim: with zero
|
|
34
|
+
* JavaScript, an attacker who controls a style value can render a
|
|
35
|
+
* full-viewport overlay (`position:fixed;inset:0` → pixel-perfect fake
|
|
36
|
+
* login UI on the customer's real domain), fire tracking/exfiltration
|
|
37
|
+
* beacons via `url(...)`, or hide and deface content. Translation data is
|
|
38
|
+
* attacker-writable in our threat model, so `sanitizeStyle` re-parses the
|
|
39
|
+
* declarations and keeps only the properties below: cosmetic text/font
|
|
40
|
+
* properties whose value grammar cannot fetch a URL and cannot reposition
|
|
41
|
+
* or restack the element (no `position`/`inset`/`display`/`z-index`/
|
|
42
|
+
* `opacity`/`transform`, no `background` shorthand). A smuggled `url(...)`
|
|
43
|
+
* inside an allowed property is doubly inert: the value is rejected here,
|
|
44
|
+
* and these properties ignore URL values anyway.
|
|
45
|
+
*
|
|
46
|
+
* CONTINUOUS DEVELOPMENT: this allowlist is intentionally minimal and is
|
|
47
|
+
* expected to grow deliberately as real sites surface legitimate inline
|
|
48
|
+
* styling the strict set drops (tracked as a WATCH item in
|
|
49
|
+
* IMPLEMENTATION.md). When extending it: (1) never add a property that
|
|
50
|
+
* accepts `url()`/`image()`/`element()` values or that affects layout,
|
|
51
|
+
* positioning, or stacking; (2) add both hostile and benign cases to
|
|
52
|
+
* html-sanitizer.test.ts; (3) mirror the change in the WordPress PHP port.
|
|
53
|
+
*/
|
|
54
|
+
export declare const SAFE_STYLE_PROPS: Set<string>;
|
|
55
|
+
/** HTML-escape text for safe use in element content or attribute values. */
|
|
56
|
+
export declare function escapeHtml(text: string): string;
|
|
57
|
+
/**
|
|
58
|
+
* Validate a URL attribute value. Returns the value unchanged when safe,
|
|
59
|
+
* or `null` when it must be dropped.
|
|
60
|
+
*
|
|
61
|
+
* Entity-decodes first, then strips the control/whitespace characters
|
|
62
|
+
* browsers ignore inside a scheme (`jav\tascript:`), then requires any
|
|
63
|
+
* explicit scheme to be on the allowlist. Scheme-less (relative) URLs pass.
|
|
64
|
+
*/
|
|
65
|
+
export declare function sanitizeUrl(value: string): string | null;
|
|
66
|
+
/**
|
|
67
|
+
* Sanitize an inline `style` attribute value by re-parsing its declarations
|
|
68
|
+
* and keeping only `SAFE_STYLE_PROPS` with clean values (see the risk note
|
|
69
|
+
* on `SAFE_STYLE_PROPS`). Returns the rebuilt declaration list in canonical
|
|
70
|
+
* `prop: value; prop: value` form, or `null` when nothing survives — the
|
|
71
|
+
* caller then drops the attribute entirely.
|
|
72
|
+
*/
|
|
73
|
+
export declare function sanitizeStyle(value: string): string | null;
|
|
74
|
+
/**
|
|
75
|
+
* Relaxed CSS profile for the snapshot viewer: keeps ANY standard property
|
|
76
|
+
* (a snapshot is a full captured page — `position:fixed` navbars and layout
|
|
77
|
+
* styles are legitimate and must render) but still rejects value-level
|
|
78
|
+
* dangers: `url(...)` beacons, `expression()`, CSS escape smuggling. The
|
|
79
|
+
* residual risk (page-authored overlay styles) is accepted for snapshots:
|
|
80
|
+
* the PM is deliberately viewing arbitrary captured pages, and the editor
|
|
81
|
+
* UI itself lives in a Shadow DOM host stacked above the snapshot root.
|
|
82
|
+
*/
|
|
83
|
+
export declare function sanitizeCssDeclarations(value: string): string | null;
|
|
84
|
+
/**
|
|
85
|
+
* Sanitize a raw opening tag (`raw:` style payload). Returns the canonical
|
|
86
|
+
* rebuilt tag with only allowlisted attributes, or `null` when the element
|
|
87
|
+
* itself is not allowed — callers must then drop the tag entirely (emit the
|
|
88
|
+
* indexed marker verbatim / skip the element).
|
|
89
|
+
*/
|
|
90
|
+
export declare function sanitizeOpeningTag(rawOpen: string): string | null;
|
|
91
|
+
/**
|
|
92
|
+
* Sanitize a ContentUnit at an ingest boundary: run every `raw:` style
|
|
93
|
+
* through {@link sanitizeOpeningTag} so no dangerous element/attribute/scheme
|
|
94
|
+
* enters the translation store. Render-time sinks (HTMLSerializer etc.)
|
|
95
|
+
* sanitize again — this is the store-side half, protecting every other
|
|
96
|
+
* consumer of stored units (server, MT/TM, exports, the WP PHP port).
|
|
97
|
+
*
|
|
98
|
+
* `text` is never modified, so `generateAutoKey(unit.text)` is unaffected —
|
|
99
|
+
* key parity across surfaces holds even for hostile input. A rejected
|
|
100
|
+
* element's `raw:` style is dropped entirely; the indexed tag left in the
|
|
101
|
+
* text is emitted by serializers as an inert marker. Returns the SAME object
|
|
102
|
+
* when nothing changed, so benign units round-trip identically.
|
|
103
|
+
*/
|
|
104
|
+
export declare function sanitizeContentUnit(unit: ContentUnit): ContentUnit;
|
|
105
|
+
//# sourceMappingURL=HTMLSanitizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HTMLSanitizer.d.ts","sourceRoot":"","sources":["../../../src/content/sanitizer/HTMLSanitizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;GAIG;AACH,eAAO,MAAM,SAAS,aAIpB,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,UAAU,aAGrB,CAAC;AAKH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,gBAAgB,aAK3B,CAAC;AAqCH,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO/C;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOxD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAE1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAEpE;AA4BD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAuCjE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW,CAyBlE"}
|