@lionrapid/core 0.1.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/README.md +106 -0
- package/dist/base/event-emitter.d.ts +91 -0
- package/dist/base/event-emitter.d.ts.map +1 -0
- package/dist/base/event-emitter.js +330 -0
- package/dist/base/event-emitter.js.map +1 -0
- package/dist/base/index.d.ts +5 -0
- package/dist/base/index.d.ts.map +1 -0
- package/dist/base/index.js +5 -0
- package/dist/base/index.js.map +1 -0
- package/dist/browser/auto-init.d.ts +57 -0
- package/dist/browser/auto-init.d.ts.map +1 -0
- package/dist/browser/auto-init.js +304 -0
- package/dist/browser/auto-init.js.map +1 -0
- package/dist/browser/auto-translator.d.ts +98 -0
- package/dist/browser/auto-translator.d.ts.map +1 -0
- package/dist/browser/auto-translator.js +218 -0
- package/dist/browser/auto-translator.js.map +1 -0
- package/dist/browser/block-extractor.d.ts +26 -0
- package/dist/browser/block-extractor.d.ts.map +1 -0
- package/dist/browser/block-extractor.js +143 -0
- package/dist/browser/block-extractor.js.map +1 -0
- package/dist/browser/dom-observer.d.ts +42 -0
- package/dist/browser/dom-observer.d.ts.map +1 -0
- package/dist/browser/dom-observer.js +109 -0
- package/dist/browser/dom-observer.js.map +1 -0
- package/dist/browser/editor/editor-api.d.ts +67 -0
- package/dist/browser/editor/editor-api.d.ts.map +1 -0
- package/dist/browser/editor/editor-api.js +233 -0
- package/dist/browser/editor/editor-api.js.map +1 -0
- package/dist/browser/editor/editor-init.d.ts +11 -0
- package/dist/browser/editor/editor-init.d.ts.map +1 -0
- package/dist/browser/editor/editor-init.js +181 -0
- package/dist/browser/editor/editor-init.js.map +1 -0
- package/dist/browser/editor/editor-styles.d.ts +6 -0
- package/dist/browser/editor/editor-styles.d.ts.map +1 -0
- package/dist/browser/editor/editor-styles.js +419 -0
- package/dist/browser/editor/editor-styles.js.map +1 -0
- package/dist/browser/editor/inspector.d.ts +22 -0
- package/dist/browser/editor/inspector.d.ts.map +1 -0
- package/dist/browser/editor/inspector.js +125 -0
- package/dist/browser/editor/inspector.js.map +1 -0
- package/dist/browser/editor/key-resolver.d.ts +19 -0
- package/dist/browser/editor/key-resolver.d.ts.map +1 -0
- package/dist/browser/editor/key-resolver.js +49 -0
- package/dist/browser/editor/key-resolver.js.map +1 -0
- package/dist/browser/editor/live-preview.d.ts +10 -0
- package/dist/browser/editor/live-preview.d.ts.map +1 -0
- package/dist/browser/editor/live-preview.js +57 -0
- package/dist/browser/editor/live-preview.js.map +1 -0
- package/dist/browser/editor/sidebar.d.ts +50 -0
- package/dist/browser/editor/sidebar.d.ts.map +1 -0
- package/dist/browser/editor/sidebar.js +353 -0
- package/dist/browser/editor/sidebar.js.map +1 -0
- package/dist/browser/editor/toolbar.d.ts +29 -0
- package/dist/browser/editor/toolbar.d.ts.map +1 -0
- package/dist/browser/editor/toolbar.js +131 -0
- package/dist/browser/editor/toolbar.js.map +1 -0
- package/dist/browser/exclude-filter.d.ts +21 -0
- package/dist/browser/exclude-filter.d.ts.map +1 -0
- package/dist/browser/exclude-filter.js +51 -0
- package/dist/browser/exclude-filter.js.map +1 -0
- package/dist/browser/index.d.ts +32 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +28 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/language-switcher.d.ts +70 -0
- package/dist/browser/language-switcher.d.ts.map +1 -0
- package/dist/browser/language-switcher.js +339 -0
- package/dist/browser/language-switcher.js.map +1 -0
- package/dist/browser/lionrapid.auto.dev.js +5757 -0
- package/dist/browser/lionrapid.auto.dev.js.map +7 -0
- package/dist/browser/lionrapid.auto.js +5757 -0
- package/dist/browser/lionrapid.auto.js.map +7 -0
- package/dist/browser/lionrapid.auto.min.js +80 -0
- package/dist/browser/lionrapid.auto.min.js.map +7 -0
- package/dist/browser/lionrapid.editor.js +1869 -0
- package/dist/browser/lionrapid.editor.js.map +7 -0
- package/dist/browser/lionrapid.editor.min.js +415 -0
- package/dist/browser/lionrapid.editor.min.js.map +7 -0
- package/dist/browser/lionrapid.esm.js +4786 -0
- package/dist/browser/lionrapid.esm.js.map +7 -0
- package/dist/browser/lionrapid.esm.min.js +3 -0
- package/dist/browser/lionrapid.esm.min.js.map +7 -0
- package/dist/browser/lionrapid.iife.dev.js +4809 -0
- package/dist/browser/lionrapid.iife.dev.js.map +7 -0
- package/dist/browser/lionrapid.iife.js +4809 -0
- package/dist/browser/lionrapid.iife.js.map +7 -0
- package/dist/browser/lionrapid.iife.min.js +3 -0
- package/dist/browser/lionrapid.iife.min.js.map +7 -0
- package/dist/browser/lionrapid.umd.js +4822 -0
- package/dist/browser/lionrapid.umd.js.map +7 -0
- package/dist/browser/lionrapid.umd.min.js +18 -0
- package/dist/browser/lionrapid.umd.min.js.map +7 -0
- package/dist/browser/markup-parser.d.ts +13 -0
- package/dist/browser/markup-parser.d.ts.map +1 -0
- package/dist/browser/markup-parser.js +56 -0
- package/dist/browser/markup-parser.js.map +1 -0
- package/dist/browser/md5.d.ts +16 -0
- package/dist/browser/md5.d.ts.map +1 -0
- package/dist/browser/md5.js +145 -0
- package/dist/browser/md5.js.map +1 -0
- package/dist/browser/storage/cache-storage-repository.d.ts +44 -0
- package/dist/browser/storage/cache-storage-repository.d.ts.map +1 -0
- package/dist/browser/storage/cache-storage-repository.js +186 -0
- package/dist/browser/storage/cache-storage-repository.js.map +1 -0
- package/dist/browser/storage/localstorage-repository.d.ts +51 -0
- package/dist/browser/storage/localstorage-repository.d.ts.map +1 -0
- package/dist/browser/storage/localstorage-repository.js +270 -0
- package/dist/browser/storage/localstorage-repository.js.map +1 -0
- package/dist/builder.d.ts +24 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +169 -0
- package/dist/builder.js.map +1 -0
- package/dist/cache/CacheManager.d.ts +132 -0
- package/dist/cache/CacheManager.d.ts.map +1 -0
- package/dist/cache/CacheManager.js +277 -0
- package/dist/cache/CacheManager.js.map +1 -0
- package/dist/cache/index.d.ts +6 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +5 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +6 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/lionrapid.config.d.ts +12 -0
- package/dist/config/lionrapid.config.d.ts.map +1 -0
- package/dist/config/lionrapid.config.js +2 -0
- package/dist/config/lionrapid.config.js.map +1 -0
- package/dist/config/logger.config.d.ts +19 -0
- package/dist/config/logger.config.d.ts.map +1 -0
- package/dist/config/logger.config.js +9 -0
- package/dist/config/logger.config.js.map +1 -0
- package/dist/config/repository.config.d.ts +87 -0
- package/dist/config/repository.config.d.ts.map +1 -0
- package/dist/config/repository.config.js +5 -0
- package/dist/config/repository.config.js.map +1 -0
- package/dist/content/index.d.ts +20 -0
- package/dist/content/index.d.ts.map +1 -0
- package/dist/content/index.js +13 -0
- package/dist/content/index.js.map +1 -0
- package/dist/content/parser/IParser.d.ts +33 -0
- package/dist/content/parser/IParser.d.ts.map +1 -0
- package/dist/content/parser/IParser.js +6 -0
- package/dist/content/parser/IParser.js.map +1 -0
- package/dist/content/parser/MarkupParser.d.ts +67 -0
- package/dist/content/parser/MarkupParser.d.ts.map +1 -0
- package/dist/content/parser/MarkupParser.js +231 -0
- package/dist/content/parser/MarkupParser.js.map +1 -0
- package/dist/content/serializer/HTMLSerializer.d.ts +61 -0
- package/dist/content/serializer/HTMLSerializer.d.ts.map +1 -0
- package/dist/content/serializer/HTMLSerializer.js +100 -0
- package/dist/content/serializer/HTMLSerializer.js.map +1 -0
- package/dist/content/serializer/ISerializer.d.ts +33 -0
- package/dist/content/serializer/ISerializer.d.ts.map +1 -0
- package/dist/content/serializer/ISerializer.js +6 -0
- package/dist/content/serializer/ISerializer.js.map +1 -0
- package/dist/content/style-mapper/DefaultStyleMapper.d.ts +59 -0
- package/dist/content/style-mapper/DefaultStyleMapper.d.ts.map +1 -0
- package/dist/content/style-mapper/DefaultStyleMapper.js +128 -0
- package/dist/content/style-mapper/DefaultStyleMapper.js.map +1 -0
- package/dist/content/style-mapper/IStyleMapper.d.ts +50 -0
- package/dist/content/style-mapper/IStyleMapper.d.ts.map +1 -0
- package/dist/content/style-mapper/IStyleMapper.js +6 -0
- package/dist/content/style-mapper/IStyleMapper.js.map +1 -0
- package/dist/content/types.d.ts +39 -0
- package/dist/content/types.d.ts.map +1 -0
- package/dist/content/types.js +6 -0
- package/dist/content/types.js.map +1 -0
- package/dist/content/validator/ContentValidator.d.ts +57 -0
- package/dist/content/validator/ContentValidator.d.ts.map +1 -0
- package/dist/content/validator/ContentValidator.js +215 -0
- package/dist/content/validator/ContentValidator.js.map +1 -0
- package/dist/content/validator/IValidator.d.ts +82 -0
- package/dist/content/validator/IValidator.d.ts.map +1 -0
- package/dist/content/validator/IValidator.js +6 -0
- package/dist/content/validator/IValidator.js.map +1 -0
- package/dist/errors/translation-errors.d.ts +55 -0
- package/dist/errors/translation-errors.d.ts.map +1 -0
- package/dist/errors/translation-errors.js +85 -0
- package/dist/errors/translation-errors.js.map +1 -0
- package/dist/handlers/async-storage-handler.d.ts +77 -0
- package/dist/handlers/async-storage-handler.d.ts.map +1 -0
- package/dist/handlers/async-storage-handler.js +239 -0
- package/dist/handlers/async-storage-handler.js.map +1 -0
- package/dist/handlers/handler-chain.d.ts +79 -0
- package/dist/handlers/handler-chain.d.ts.map +1 -0
- package/dist/handlers/handler-chain.js +366 -0
- package/dist/handlers/handler-chain.js.map +1 -0
- package/dist/handlers/index.d.ts +7 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +7 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/handlers/network-handler.d.ts +90 -0
- package/dist/handlers/network-handler.d.ts.map +1 -0
- package/dist/handlers/network-handler.js +283 -0
- package/dist/handlers/network-handler.js.map +1 -0
- package/dist/handlers/sync-storage-handler.d.ts +88 -0
- package/dist/handlers/sync-storage-handler.d.ts.map +1 -0
- package/dist/handlers/sync-storage-handler.js +270 -0
- package/dist/handlers/sync-storage-handler.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/emitter.interface.d.ts +33 -0
- package/dist/interfaces/emitter.interface.d.ts.map +1 -0
- package/dist/interfaces/emitter.interface.js +2 -0
- package/dist/interfaces/emitter.interface.js.map +1 -0
- package/dist/interfaces/handler.interface.d.ts +50 -0
- package/dist/interfaces/handler.interface.d.ts.map +1 -0
- package/dist/interfaces/handler.interface.js +5 -0
- package/dist/interfaces/handler.interface.js.map +1 -0
- package/dist/interfaces/index.d.ts +8 -0
- package/dist/interfaces/index.d.ts.map +1 -0
- package/dist/interfaces/index.js +8 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/interfaces/plugin.interface.d.ts +49 -0
- package/dist/interfaces/plugin.interface.d.ts.map +1 -0
- package/dist/interfaces/plugin.interface.js +6 -0
- package/dist/interfaces/plugin.interface.js.map +1 -0
- package/dist/interfaces/repository.interface.d.ts +56 -0
- package/dist/interfaces/repository.interface.d.ts.map +1 -0
- package/dist/interfaces/repository.interface.js +2 -0
- package/dist/interfaces/repository.interface.js.map +1 -0
- package/dist/lionRapid.d.ts +225 -0
- package/dist/lionRapid.d.ts.map +1 -0
- package/dist/lionRapid.js +596 -0
- package/dist/lionRapid.js.map +1 -0
- package/dist/repositories/index.d.ts +3 -0
- package/dist/repositories/index.d.ts.map +1 -0
- package/dist/repositories/index.js +3 -0
- package/dist/repositories/index.js.map +1 -0
- package/dist/repositories/memory-repository.d.ts +30 -0
- package/dist/repositories/memory-repository.d.ts.map +1 -0
- package/dist/repositories/memory-repository.js +100 -0
- package/dist/repositories/memory-repository.js.map +1 -0
- package/dist/repositories/network-repository.d.ts +138 -0
- package/dist/repositories/network-repository.d.ts.map +1 -0
- package/dist/repositories/network-repository.js +516 -0
- package/dist/repositories/network-repository.js.map +1 -0
- package/dist/sync/missing-translation-queue.d.ts +64 -0
- package/dist/sync/missing-translation-queue.d.ts.map +1 -0
- package/dist/sync/missing-translation-queue.js +184 -0
- package/dist/sync/missing-translation-queue.js.map +1 -0
- package/dist/types/cache.types.d.ts +62 -0
- package/dist/types/cache.types.d.ts.map +1 -0
- package/dist/types/cache.types.js +6 -0
- package/dist/types/cache.types.js.map +1 -0
- package/dist/types/event-payloads.types.d.ts +46 -0
- package/dist/types/event-payloads.types.d.ts.map +1 -0
- package/dist/types/event-payloads.types.js +6 -0
- package/dist/types/event-payloads.types.js.map +1 -0
- package/dist/types/generated.types.d.ts +31 -0
- package/dist/types/generated.types.d.ts.map +1 -0
- package/dist/types/generated.types.js +6 -0
- package/dist/types/generated.types.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/lionRapid.types.d.ts +169 -0
- package/dist/types/lionRapid.types.d.ts.map +1 -0
- package/dist/types/lionRapid.types.js +8 -0
- package/dist/types/lionRapid.types.js.map +1 -0
- package/dist/types/parameters.types.d.ts +36 -0
- package/dist/types/parameters.types.d.ts.map +1 -0
- package/dist/types/parameters.types.js +6 -0
- package/dist/types/parameters.types.js.map +1 -0
- package/dist/types/translation-data.types.d.ts +54 -0
- package/dist/types/translation-data.types.d.ts.map +1 -0
- package/dist/types/translation-data.types.js +6 -0
- package/dist/types/translation-data.types.js.map +1 -0
- package/dist/types/translation.types.d.ts +94 -0
- package/dist/types/translation.types.d.ts.map +1 -0
- package/dist/types/translation.types.js +5 -0
- package/dist/types/translation.types.js.map +1 -0
- package/dist/utils/context-utils.d.ts +23 -0
- package/dist/utils/context-utils.d.ts.map +1 -0
- package/dist/utils/context-utils.js +36 -0
- package/dist/utils/context-utils.js.map +1 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +19 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +229 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +345 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/namespace-utils.d.ts +30 -0
- package/dist/utils/namespace-utils.d.ts.map +1 -0
- package/dist/utils/namespace-utils.js +56 -0
- package/dist/utils/namespace-utils.js.map +1 -0
- package/dist/utils/translation-flow.d.ts +18 -0
- package/dist/utils/translation-flow.d.ts.map +1 -0
- package/dist/utils/translation-flow.js +74 -0
- package/dist/utils/translation-flow.js.map +1 -0
- package/dist/utils/translation-value-utils.d.ts +57 -0
- package/dist/utils/translation-value-utils.d.ts.map +1 -0
- package/dist/utils/translation-value-utils.js +194 -0
- package/dist/utils/translation-value-utils.js.map +1 -0
- package/package.json +76 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default style mapper for bidirectional HTML element ↔ style property mapping
|
|
3
|
+
* @module content/style-mapper/DefaultStyleMapper
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Default implementation of style mapping
|
|
7
|
+
*
|
|
8
|
+
* Provides bidirectional conversion between HTML elements and style properties:
|
|
9
|
+
* - mapElementToStyles: `<b>` → `["bold"]`
|
|
10
|
+
* - mapStylesToElement: `["bold"]` → `<b>`
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const mapper = new DefaultStyleMapper();
|
|
15
|
+
*
|
|
16
|
+
* // Parsing: HTML → styles
|
|
17
|
+
* mapper.mapElementToStyles('a', { href: '/terms' });
|
|
18
|
+
* // → ["hyperlink:/terms"]
|
|
19
|
+
*
|
|
20
|
+
* // Serializing: styles → HTML
|
|
21
|
+
* mapper.mapStylesToElement(['bold', 'hyperlink:/terms']);
|
|
22
|
+
* // → { element: 'a', attrs: { href: '/terms' } }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export class DefaultStyleMapper {
|
|
26
|
+
/**
|
|
27
|
+
* Element → Style mapping
|
|
28
|
+
* Maps HTML element names to their style property
|
|
29
|
+
*/
|
|
30
|
+
elementToStyles = {
|
|
31
|
+
b: 'bold',
|
|
32
|
+
strong: 'bold',
|
|
33
|
+
i: 'italic',
|
|
34
|
+
em: 'italic',
|
|
35
|
+
u: 'underline',
|
|
36
|
+
s: 'strikethrough',
|
|
37
|
+
del: 'strikethrough',
|
|
38
|
+
strike: 'strikethrough',
|
|
39
|
+
code: 'code',
|
|
40
|
+
mark: 'highlight',
|
|
41
|
+
sub: 'subscript',
|
|
42
|
+
sup: 'superscript',
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Style → Element mapping (reverse)
|
|
46
|
+
* Uses simple, familiar elements for developer convenience
|
|
47
|
+
* Also accepts element names directly (strong, em, etc.)
|
|
48
|
+
*/
|
|
49
|
+
styleToElement = {
|
|
50
|
+
// Semantic style names → simple elements
|
|
51
|
+
bold: 'b',
|
|
52
|
+
italic: 'i',
|
|
53
|
+
underline: 'u',
|
|
54
|
+
strikethrough: 's',
|
|
55
|
+
code: 'code',
|
|
56
|
+
highlight: 'mark',
|
|
57
|
+
subscript: 'sub',
|
|
58
|
+
superscript: 'sup',
|
|
59
|
+
// Element names (for servers that store styles as element names)
|
|
60
|
+
strong: 'b',
|
|
61
|
+
b: 'b',
|
|
62
|
+
em: 'i',
|
|
63
|
+
i: 'i',
|
|
64
|
+
u: 'u',
|
|
65
|
+
s: 's',
|
|
66
|
+
del: 's',
|
|
67
|
+
strike: 's',
|
|
68
|
+
mark: 'mark',
|
|
69
|
+
sub: 'sub',
|
|
70
|
+
sup: 'sup',
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Convert HTML element to style properties
|
|
74
|
+
*
|
|
75
|
+
* @param element - Tag name (e.g., "b", "a", "strong")
|
|
76
|
+
* @param attrs - Element attributes (e.g., { href: "/url" })
|
|
77
|
+
* @returns Array of style strings
|
|
78
|
+
*/
|
|
79
|
+
mapElementToStyles(element, attrs) {
|
|
80
|
+
const styles = [];
|
|
81
|
+
const tag = element.toLowerCase();
|
|
82
|
+
// Basic element mapping
|
|
83
|
+
const mappedStyle = this.elementToStyles[tag];
|
|
84
|
+
if (mappedStyle) {
|
|
85
|
+
styles.push(mappedStyle);
|
|
86
|
+
}
|
|
87
|
+
// Special: <a href="..."> → hyperlink:url
|
|
88
|
+
if (tag === 'a' && attrs.href) {
|
|
89
|
+
styles.push(`hyperlink:${attrs.href}`);
|
|
90
|
+
}
|
|
91
|
+
return styles;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Convert style properties to HTML element
|
|
95
|
+
*
|
|
96
|
+
* Priority order:
|
|
97
|
+
* 1. Hyperlink (becomes wrapper element with href)
|
|
98
|
+
* 2. First recognized style property
|
|
99
|
+
* 3. Fallback to span
|
|
100
|
+
*
|
|
101
|
+
* @param styles - Array of style strings
|
|
102
|
+
* @returns Element info for serialization
|
|
103
|
+
*/
|
|
104
|
+
mapStylesToElement(styles) {
|
|
105
|
+
// Check for hyperlink first (takes priority as wrapper element)
|
|
106
|
+
for (const style of styles) {
|
|
107
|
+
if (style.startsWith('hyperlink:')) {
|
|
108
|
+
return {
|
|
109
|
+
element: 'a',
|
|
110
|
+
attrs: { href: style.slice('hyperlink:'.length) },
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Map first recognized style to element
|
|
115
|
+
for (const style of styles) {
|
|
116
|
+
const element = this.styleToElement[style];
|
|
117
|
+
if (element) {
|
|
118
|
+
return {
|
|
119
|
+
element,
|
|
120
|
+
attrs: {},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Fallback: span with no special attributes
|
|
125
|
+
return { element: 'span', attrs: {} };
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=DefaultStyleMapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DefaultStyleMapper.js","sourceRoot":"","sources":["../../../src/content/style-mapper/DefaultStyleMapper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,kBAAkB;IAC7B;;;OAGG;IACc,eAAe,GAA2B;QACzD,CAAC,EAAE,MAAM;QACT,MAAM,EAAE,MAAM;QACd,CAAC,EAAE,QAAQ;QACX,EAAE,EAAE,QAAQ;QACZ,CAAC,EAAE,WAAW;QACd,CAAC,EAAE,eAAe;QAClB,GAAG,EAAE,eAAe;QACpB,MAAM,EAAE,eAAe;QACvB,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,WAAW;QACjB,GAAG,EAAE,WAAW;QAChB,GAAG,EAAE,aAAa;KACnB,CAAC;IAEF;;;;OAIG;IACc,cAAc,GAA2B;QACxD,yCAAyC;QACzC,IAAI,EAAE,GAAG;QACT,MAAM,EAAE,GAAG;QACX,SAAS,EAAE,GAAG;QACd,aAAa,EAAE,GAAG;QAClB,IAAI,EAAE,MAAM;QACZ,SAAS,EAAE,MAAM;QACjB,SAAS,EAAE,KAAK;QAChB,WAAW,EAAE,KAAK;QAClB,iEAAiE;QACjE,MAAM,EAAE,GAAG;QACX,CAAC,EAAE,GAAG;QACN,EAAE,EAAE,GAAG;QACP,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,GAAG;QACN,CAAC,EAAE,GAAG;QACN,GAAG,EAAE,GAAG;QACR,MAAM,EAAE,GAAG;QACX,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,KAAK;QACV,GAAG,EAAE,KAAK;KACX,CAAC;IAEF;;;;;;OAMG;IACH,kBAAkB,CAAC,OAAe,EAAE,KAA6B;QAC/D,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;QAElC,wBAAwB;QACxB,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC3B,CAAC;QAED,0CAA0C;QAC1C,IAAI,GAAG,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;;;OAUG;IACH,kBAAkB,CAAC,MAAgB;QACjC,gEAAgE;QAChE,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBACnC,OAAO;oBACL,OAAO,EAAE,GAAG;oBACZ,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE;iBAClD,CAAC;YACJ,CAAC;QACH,CAAC;QAED,wCAAwC;QACxC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;YAC3C,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO;oBACL,OAAO;oBACP,KAAK,EAAE,EAAE;iBACV,CAAC;YACJ,CAAC;QACH,CAAC;QAED,4CAA4C;QAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IACxC,CAAC;CACF"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Style mapper interface for bidirectional HTML element ↔ style property mapping
|
|
3
|
+
* @module content/style-mapper/IStyleMapper
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Result of mapping styles to an HTML element
|
|
7
|
+
*/
|
|
8
|
+
export interface ElementMapping {
|
|
9
|
+
/**
|
|
10
|
+
* HTML element tag name (e.g., "b", "a", "span")
|
|
11
|
+
*/
|
|
12
|
+
element: string;
|
|
13
|
+
/**
|
|
14
|
+
* HTML attributes (e.g., { href: "/terms" })
|
|
15
|
+
*/
|
|
16
|
+
attrs: Record<string, string>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Bidirectional mapper between HTML elements and style properties
|
|
20
|
+
*
|
|
21
|
+
* Used by:
|
|
22
|
+
* - MarkupParser: element → styles (parsing HTML)
|
|
23
|
+
* - HTMLSerializer: styles → element (generating HTML)
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* class DefaultStyleMapper implements IStyleMapper {
|
|
28
|
+
* mapElementToStyles("a", { href: "/terms" }) // → ["hyperlink:/terms"]
|
|
29
|
+
* mapStylesToElement(["bold", "hyperlink:/terms"]) // → { element: "a", attrs: { href: "/terms" } }
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export interface IStyleMapper {
|
|
34
|
+
/**
|
|
35
|
+
* Convert HTML element to style properties
|
|
36
|
+
*
|
|
37
|
+
* @param element - Tag name (e.g., "b", "a", "strong")
|
|
38
|
+
* @param attrs - Element attributes (e.g., { href: "/url" })
|
|
39
|
+
* @returns Array of style strings (e.g., ["bold", "hyperlink:/url"])
|
|
40
|
+
*/
|
|
41
|
+
mapElementToStyles(element: string, attrs: Record<string, string>): string[];
|
|
42
|
+
/**
|
|
43
|
+
* Convert style properties to HTML element
|
|
44
|
+
*
|
|
45
|
+
* @param styles - Array of style strings
|
|
46
|
+
* @returns Element info for serialization
|
|
47
|
+
*/
|
|
48
|
+
mapStylesToElement(styles: string[]): ElementMapping;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=IStyleMapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IStyleMapper.d.ts","sourceRoot":"","sources":["../../../src/content/style-mapper/IStyleMapper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;;OAMG;IACH,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC;IAE7E;;;;;OAKG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,cAAc,CAAC;CACtD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IStyleMapper.js","sourceRoot":"","sources":["../../../src/content/style-mapper/IStyleMapper.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core content types for the Unified Content Architecture
|
|
3
|
+
* @module content/types
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* ContentUnit - Universal representation of styled translatable content
|
|
7
|
+
*
|
|
8
|
+
* Uses indexed tags (1-based) to represent styled regions:
|
|
9
|
+
* - Text: "Hello <1>world</1>"
|
|
10
|
+
* - Styles: { "1": ["bold"] }
|
|
11
|
+
*
|
|
12
|
+
* ICU parameter schema is provided at the namespace level by the server,
|
|
13
|
+
* not per-translation. See the `schema` field in server responses.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const unit: ContentUnit = {
|
|
18
|
+
* text: "Read our <1>Terms</1> and <2>Privacy</2>.",
|
|
19
|
+
* styles: {
|
|
20
|
+
* "1": ["bold", "hyperlink:/terms"],
|
|
21
|
+
* "2": ["hyperlink:/privacy"]
|
|
22
|
+
* }
|
|
23
|
+
* };
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export interface ContentUnit {
|
|
27
|
+
/**
|
|
28
|
+
* Text with indexed tags: "Hello <1>world</1>"
|
|
29
|
+
* Tags are 1-based integers matching keys in styles
|
|
30
|
+
*/
|
|
31
|
+
text: string;
|
|
32
|
+
/**
|
|
33
|
+
* Style definitions by tag index
|
|
34
|
+
* Key: tag index as string (e.g., "1", "2")
|
|
35
|
+
* Value: array of style properties (e.g., ["bold", "hyperlink:/url"])
|
|
36
|
+
*/
|
|
37
|
+
styles: Record<string, string[]>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/content/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAClC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/content/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content validator for ContentUnit integrity checking
|
|
3
|
+
* @module content/validator/ContentValidator
|
|
4
|
+
*/
|
|
5
|
+
import type { IValidator, ValidationResult } from './IValidator.js';
|
|
6
|
+
import type { ContentUnit } from '../types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Validates ContentUnit for structural integrity
|
|
9
|
+
*
|
|
10
|
+
* Checks for:
|
|
11
|
+
* - Balanced indexed tags (`<1>...</1>`)
|
|
12
|
+
* - Valid tag indices (no invalid/malformed tags)
|
|
13
|
+
* - Style references (styles referenced by tags exist)
|
|
14
|
+
* - Orphan styles (styles defined but not used)
|
|
15
|
+
* - Basic ICU brace balance validation
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const validator = new ContentValidator();
|
|
20
|
+
*
|
|
21
|
+
* // Valid unit
|
|
22
|
+
* const valid = validator.validate({
|
|
23
|
+
* text: 'Hello <1>world</1>',
|
|
24
|
+
* styles: { '1': ['bold'] }
|
|
25
|
+
* });
|
|
26
|
+
* // → { valid: true, errors: [], warnings: [] }
|
|
27
|
+
*
|
|
28
|
+
* // Unbalanced tags
|
|
29
|
+
* const invalid = validator.validate({
|
|
30
|
+
* text: 'Hello <1>world',
|
|
31
|
+
* styles: { '1': ['bold'] }
|
|
32
|
+
* });
|
|
33
|
+
* // → { valid: false, errors: [{ code: 'UNBALANCED_TAGS', ... }], ... }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare class ContentValidator implements IValidator {
|
|
37
|
+
/**
|
|
38
|
+
* Validate a ContentUnit for structural integrity
|
|
39
|
+
*
|
|
40
|
+
* @param unit - ContentUnit to validate
|
|
41
|
+
* @returns Validation result with errors and warnings
|
|
42
|
+
*/
|
|
43
|
+
validate(unit: ContentUnit): ValidationResult;
|
|
44
|
+
/**
|
|
45
|
+
* Validate that all indexed tags are properly balanced and correctly nested
|
|
46
|
+
*/
|
|
47
|
+
private validateTagBalance;
|
|
48
|
+
/**
|
|
49
|
+
* Validate style references - check that used tags have styles and vice versa
|
|
50
|
+
*/
|
|
51
|
+
private validateStyleReferences;
|
|
52
|
+
/**
|
|
53
|
+
* Validate ICU MessageFormat brace balance
|
|
54
|
+
*/
|
|
55
|
+
private validateICUBraces;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=ContentValidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContentValidator.d.ts","sourceRoot":"","sources":["../../../src/content/validator/ContentValidator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,gBAAgB,EAKjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,gBAAiB,YAAW,UAAU;IACjD;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,gBAAgB;IAoB7C;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAmE1B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAqC/B;;OAEG;IACH,OAAO,CAAC,iBAAiB;CA+D1B"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content validator for ContentUnit integrity checking
|
|
3
|
+
* @module content/validator/ContentValidator
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Validates ContentUnit for structural integrity
|
|
7
|
+
*
|
|
8
|
+
* Checks for:
|
|
9
|
+
* - Balanced indexed tags (`<1>...</1>`)
|
|
10
|
+
* - Valid tag indices (no invalid/malformed tags)
|
|
11
|
+
* - Style references (styles referenced by tags exist)
|
|
12
|
+
* - Orphan styles (styles defined but not used)
|
|
13
|
+
* - Basic ICU brace balance validation
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const validator = new ContentValidator();
|
|
18
|
+
*
|
|
19
|
+
* // Valid unit
|
|
20
|
+
* const valid = validator.validate({
|
|
21
|
+
* text: 'Hello <1>world</1>',
|
|
22
|
+
* styles: { '1': ['bold'] }
|
|
23
|
+
* });
|
|
24
|
+
* // → { valid: true, errors: [], warnings: [] }
|
|
25
|
+
*
|
|
26
|
+
* // Unbalanced tags
|
|
27
|
+
* const invalid = validator.validate({
|
|
28
|
+
* text: 'Hello <1>world',
|
|
29
|
+
* styles: { '1': ['bold'] }
|
|
30
|
+
* });
|
|
31
|
+
* // → { valid: false, errors: [{ code: 'UNBALANCED_TAGS', ... }], ... }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export class ContentValidator {
|
|
35
|
+
/**
|
|
36
|
+
* Validate a ContentUnit for structural integrity
|
|
37
|
+
*
|
|
38
|
+
* @param unit - ContentUnit to validate
|
|
39
|
+
* @returns Validation result with errors and warnings
|
|
40
|
+
*/
|
|
41
|
+
validate(unit) {
|
|
42
|
+
const errors = [];
|
|
43
|
+
const warnings = [];
|
|
44
|
+
// Check tag balance
|
|
45
|
+
this.validateTagBalance(unit.text, errors);
|
|
46
|
+
// Check style references
|
|
47
|
+
this.validateStyleReferences(unit.text, unit.styles, errors, warnings);
|
|
48
|
+
// Check ICU brace balance (always, since text may contain ICU patterns)
|
|
49
|
+
this.validateICUBraces(unit.text, errors);
|
|
50
|
+
return {
|
|
51
|
+
valid: errors.length === 0,
|
|
52
|
+
errors,
|
|
53
|
+
warnings,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Validate that all indexed tags are properly balanced and correctly nested
|
|
58
|
+
*/
|
|
59
|
+
validateTagBalance(text, errors) {
|
|
60
|
+
// Pattern to match indexed tags: <1>, </1>, <1/>
|
|
61
|
+
const tagPattern = /<(\/?)?(\d+)(\/)?>/g;
|
|
62
|
+
// Stack-based approach to verify proper nesting order
|
|
63
|
+
const tagStack = [];
|
|
64
|
+
let match;
|
|
65
|
+
while ((match = tagPattern.exec(text)) !== null) {
|
|
66
|
+
const [, closingSlash, indexStr, selfClosingSlash] = match;
|
|
67
|
+
if (selfClosingSlash) {
|
|
68
|
+
// Self-closing tag: <1/> - always valid
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
if (closingSlash) {
|
|
72
|
+
// Closing tag: </1>
|
|
73
|
+
// Must match the most recently opened tag (proper nesting)
|
|
74
|
+
if (tagStack.length === 0) {
|
|
75
|
+
errors.push({
|
|
76
|
+
code: 'UNBALANCED_TAGS',
|
|
77
|
+
message: `Closing tag </${indexStr}> has no matching opening tag`,
|
|
78
|
+
path: `text[${match.index}]`,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const lastOpen = tagStack[tagStack.length - 1];
|
|
83
|
+
if (lastOpen.index === indexStr) {
|
|
84
|
+
// Proper closing - pop the stack
|
|
85
|
+
tagStack.pop();
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Check if this tag was opened earlier (improper nesting)
|
|
89
|
+
const foundIndex = tagStack.findIndex((t) => t.index === indexStr);
|
|
90
|
+
if (foundIndex >= 0) {
|
|
91
|
+
// Tag was opened but not in the right order
|
|
92
|
+
errors.push({
|
|
93
|
+
code: 'UNBALANCED_TAGS',
|
|
94
|
+
message: `Improperly nested: </${indexStr}> should close before </${lastOpen.index}>`,
|
|
95
|
+
path: `text[${match.index}]`,
|
|
96
|
+
});
|
|
97
|
+
// Remove the out-of-order tag from stack
|
|
98
|
+
tagStack.splice(foundIndex, 1);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
// Tag was never opened
|
|
102
|
+
errors.push({
|
|
103
|
+
code: 'UNBALANCED_TAGS',
|
|
104
|
+
message: `Closing tag </${indexStr}> has no matching opening tag`,
|
|
105
|
+
path: `text[${match.index}]`,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
// Opening tag: <1>
|
|
113
|
+
tagStack.push({ index: indexStr, position: match.index });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Check for unclosed tags
|
|
117
|
+
for (const { index } of tagStack) {
|
|
118
|
+
errors.push({
|
|
119
|
+
code: 'UNBALANCED_TAGS',
|
|
120
|
+
message: `Opening tag <${index}> has no matching closing tag`,
|
|
121
|
+
path: 'text',
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Validate style references - check that used tags have styles and vice versa
|
|
127
|
+
*/
|
|
128
|
+
validateStyleReferences(text, styles, errors, warnings) {
|
|
129
|
+
// Find all tag indices used in text
|
|
130
|
+
const usedIndices = new Set();
|
|
131
|
+
const tagPattern = /<\/?(\d+)(?:\/)?>/g;
|
|
132
|
+
let match;
|
|
133
|
+
while ((match = tagPattern.exec(text)) !== null) {
|
|
134
|
+
usedIndices.add(match[1]);
|
|
135
|
+
}
|
|
136
|
+
// Check for used indices without style definitions
|
|
137
|
+
for (const index of usedIndices) {
|
|
138
|
+
if (!styles[index] || styles[index].length === 0) {
|
|
139
|
+
// This is a warning, not an error - tag will render as <span>
|
|
140
|
+
warnings.push({
|
|
141
|
+
code: 'EMPTY_STYLE',
|
|
142
|
+
message: `Tag <${index}> has no style definition, will render as <span>`,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// Check for defined styles not used in text (orphan styles)
|
|
147
|
+
for (const index of Object.keys(styles)) {
|
|
148
|
+
if (!usedIndices.has(index)) {
|
|
149
|
+
warnings.push({
|
|
150
|
+
code: 'UNUSED_TAG',
|
|
151
|
+
message: `Style for tag <${index}> is defined but tag is not used in text`,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Validate ICU MessageFormat brace balance
|
|
158
|
+
*/
|
|
159
|
+
validateICUBraces(text, errors) {
|
|
160
|
+
// Check for balanced braces
|
|
161
|
+
let depth = 0;
|
|
162
|
+
let inString = false;
|
|
163
|
+
let stringChar = '';
|
|
164
|
+
for (let i = 0; i < text.length; i++) {
|
|
165
|
+
const char = text[i];
|
|
166
|
+
const prevChar = i > 0 ? text[i - 1] : '';
|
|
167
|
+
// Handle string escaping
|
|
168
|
+
if ((char === '"' || char === "'") &&
|
|
169
|
+
prevChar !== '\\') {
|
|
170
|
+
if (!inString) {
|
|
171
|
+
inString = true;
|
|
172
|
+
stringChar = char;
|
|
173
|
+
}
|
|
174
|
+
else if (char === stringChar) {
|
|
175
|
+
inString = false;
|
|
176
|
+
stringChar = '';
|
|
177
|
+
}
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
if (inString)
|
|
181
|
+
continue;
|
|
182
|
+
if (char === '{') {
|
|
183
|
+
depth++;
|
|
184
|
+
}
|
|
185
|
+
else if (char === '}') {
|
|
186
|
+
depth--;
|
|
187
|
+
if (depth < 0) {
|
|
188
|
+
errors.push({
|
|
189
|
+
code: 'INVALID_ICU',
|
|
190
|
+
message: `Unbalanced ICU braces: unexpected '}' at position ${i}`,
|
|
191
|
+
path: `text[${i}]`,
|
|
192
|
+
});
|
|
193
|
+
depth = 0; // Reset to continue checking
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (depth > 0) {
|
|
198
|
+
errors.push({
|
|
199
|
+
code: 'INVALID_ICU',
|
|
200
|
+
message: `Unbalanced ICU braces: ${depth} unclosed '{'`,
|
|
201
|
+
path: 'text',
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
// Check for empty variable names
|
|
205
|
+
const emptyVarPattern = /\{\s*[,}]/;
|
|
206
|
+
if (emptyVarPattern.test(text)) {
|
|
207
|
+
errors.push({
|
|
208
|
+
code: 'INVALID_ICU',
|
|
209
|
+
message: 'ICU variable name is empty or missing',
|
|
210
|
+
path: 'text',
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=ContentValidator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContentValidator.js","sourceRoot":"","sources":["../../../src/content/validator/ContentValidator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validator interface and result types for ContentUnit validation
|
|
3
|
+
* @module content/validator/IValidator
|
|
4
|
+
*/
|
|
5
|
+
import type { ContentUnit } from '../types.js';
|
|
6
|
+
/**
|
|
7
|
+
* Validation error codes
|
|
8
|
+
*/
|
|
9
|
+
export type ValidationErrorCode = 'UNBALANCED_TAGS' | 'INVALID_TAG_INDEX' | 'ORPHAN_STYLE' | 'INVALID_ICU';
|
|
10
|
+
/**
|
|
11
|
+
* Validation warning codes
|
|
12
|
+
*/
|
|
13
|
+
export type ValidationWarningCode = 'EMPTY_STYLE' | 'UNUSED_TAG';
|
|
14
|
+
/**
|
|
15
|
+
* Validation error details
|
|
16
|
+
*/
|
|
17
|
+
export interface ValidationError {
|
|
18
|
+
/**
|
|
19
|
+
* Error code identifying the type of error
|
|
20
|
+
*/
|
|
21
|
+
code: ValidationErrorCode;
|
|
22
|
+
/**
|
|
23
|
+
* Human-readable error message
|
|
24
|
+
*/
|
|
25
|
+
message: string;
|
|
26
|
+
/**
|
|
27
|
+
* Path to the error location (e.g., "text", "styles.1")
|
|
28
|
+
*/
|
|
29
|
+
path?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Validation warning details
|
|
33
|
+
*/
|
|
34
|
+
export interface ValidationWarning {
|
|
35
|
+
/**
|
|
36
|
+
* Warning code identifying the type of warning
|
|
37
|
+
*/
|
|
38
|
+
code: ValidationWarningCode;
|
|
39
|
+
/**
|
|
40
|
+
* Human-readable warning message
|
|
41
|
+
*/
|
|
42
|
+
message: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Validation result containing errors and warnings
|
|
46
|
+
*/
|
|
47
|
+
export interface ValidationResult {
|
|
48
|
+
/**
|
|
49
|
+
* Whether the ContentUnit is valid (no errors)
|
|
50
|
+
*/
|
|
51
|
+
valid: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* List of validation errors (blocking issues)
|
|
54
|
+
*/
|
|
55
|
+
errors: ValidationError[];
|
|
56
|
+
/**
|
|
57
|
+
* List of validation warnings (non-blocking issues)
|
|
58
|
+
*/
|
|
59
|
+
warnings: ValidationWarning[];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Validator interface for ContentUnit integrity checks
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* class ContentValidator implements IValidator {
|
|
67
|
+
* validate(unit: ContentUnit): ValidationResult {
|
|
68
|
+
* // Check balanced tags, orphan styles, ICU syntax
|
|
69
|
+
* }
|
|
70
|
+
* }
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export interface IValidator {
|
|
74
|
+
/**
|
|
75
|
+
* Validate ContentUnit integrity
|
|
76
|
+
*
|
|
77
|
+
* @param unit - The ContentUnit to validate
|
|
78
|
+
* @returns Validation result with errors and warnings
|
|
79
|
+
*/
|
|
80
|
+
validate(unit: ContentUnit): ValidationResult;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=IValidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IValidator.d.ts","sourceRoot":"","sources":["../../../src/content/validator/IValidator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAC3B,iBAAiB,GACjB,mBAAmB,GACnB,cAAc,GACd,aAAa,CAAC;AAElB;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,aAAa,GAAG,YAAY,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,IAAI,EAAE,mBAAmB,CAAC;IAE1B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,IAAI,EAAE,qBAAqB,CAAC;IAE5B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,MAAM,EAAE,eAAe,EAAE,CAAC;IAE1B;;OAEG;IACH,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,UAAU;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,gBAAgB,CAAC;CAC/C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IValidator.js","sourceRoot":"","sources":["../../../src/content/validator/IValidator.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|