@pecb-ui/components 1.1.2 → 1.2.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 +556 -556
- package/fesm2022/pecb-ui-components.mjs +3826 -1945
- package/fesm2022/pecb-ui-components.mjs.map +1 -1
- package/index.d.ts +3937 -3
- package/package.json +6 -8
- package/esm2022/lib/components/button/button.component.mjs +0 -171
- package/esm2022/lib/components/card/card.component.mjs +0 -182
- package/esm2022/lib/components/checkbox/checkbox.component.mjs +0 -126
- package/esm2022/lib/components/datepicker/datepicker.component.mjs +0 -349
- package/esm2022/lib/components/dropdown/dropdown.component.mjs +0 -329
- package/esm2022/lib/components/input/input.component.mjs +0 -321
- package/esm2022/lib/components/pagination/pagination.component.mjs +0 -197
- package/esm2022/lib/components/radio/radio.component.mjs +0 -147
- package/esm2022/lib/components/right-modal/right-modal.component.mjs +0 -234
- package/esm2022/lib/components/sidebar/sidebar.component.mjs +0 -155
- package/esm2022/lib/components/status/status.component.mjs +0 -50
- package/esm2022/lib/components/tab/tab.component.mjs +0 -151
- package/esm2022/lib/components/table/table.component.mjs +0 -503
- package/esm2022/lib/components/toggle/toggle.component.mjs +0 -126
- package/esm2022/lib/pecb-components.module.mjs +0 -118
- package/esm2022/lib/services/loading.service.mjs +0 -182
- package/esm2022/lib/services/notification.service.mjs +0 -144
- package/esm2022/lib/services/theme.service.mjs +0 -232
- package/esm2022/lib/shared/interfaces/component.interfaces.mjs +0 -2
- package/esm2022/lib/shared/types/common.types.mjs +0 -6
- package/esm2022/lib/shared/utils/accessibility.utils.mjs +0 -223
- package/esm2022/lib/shared/utils/dom.utils.mjs +0 -240
- package/esm2022/lib/shared/utils/error.utils.mjs +0 -277
- package/esm2022/lib/shared/utils/string.utils.mjs +0 -204
- package/esm2022/pecb-ui-components.mjs +0 -5
- package/esm2022/public-api.mjs +0 -53
- package/lib/components/button/button.component.d.ts +0 -130
- package/lib/components/card/card.component.d.ts +0 -140
- package/lib/components/checkbox/checkbox.component.d.ts +0 -74
- package/lib/components/datepicker/datepicker.component.d.ts +0 -155
- package/lib/components/dropdown/dropdown.component.d.ts +0 -144
- package/lib/components/input/input.component.d.ts +0 -215
- package/lib/components/pagination/pagination.component.d.ts +0 -53
- package/lib/components/radio/radio.component.d.ts +0 -93
- package/lib/components/right-modal/right-modal.component.d.ts +0 -137
- package/lib/components/sidebar/sidebar.component.d.ts +0 -97
- package/lib/components/status/status.component.d.ts +0 -19
- package/lib/components/tab/tab.component.d.ts +0 -102
- package/lib/components/table/table.component.d.ts +0 -403
- package/lib/components/toggle/toggle.component.d.ts +0 -74
- package/lib/pecb-components.module.d.ts +0 -37
- package/lib/services/loading.service.d.ts +0 -129
- package/lib/services/notification.service.d.ts +0 -136
- package/lib/services/theme.service.d.ts +0 -142
- package/lib/shared/interfaces/component.interfaces.d.ts +0 -283
- package/lib/shared/types/common.types.d.ts +0 -86
- package/lib/shared/utils/accessibility.utils.d.ts +0 -167
- package/lib/shared/utils/dom.utils.d.ts +0 -108
- package/lib/shared/utils/error.utils.d.ts +0 -191
- package/lib/shared/utils/string.utils.d.ts +0 -144
- package/public-api.d.ts +0 -24
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DOM utility functions for PECB UI Components
|
|
3
|
-
* @module utils/dom
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Check if code is running in a browser environment
|
|
7
|
-
* @returns True if running in browser
|
|
8
|
-
*/
|
|
9
|
-
export function isBrowser() {
|
|
10
|
-
return typeof window !== 'undefined' && typeof document !== 'undefined';
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Generate a unique ID for DOM elements
|
|
14
|
-
* @param prefix - Optional prefix for the ID
|
|
15
|
-
* @returns A unique ID string
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* generateUniqueId('btn') // 'btn-a1b2c3d4'
|
|
19
|
-
*/
|
|
20
|
-
export function generateUniqueId(prefix = 'pecb') {
|
|
21
|
-
const random = Math.random().toString(36).substring(2, 9);
|
|
22
|
-
return `${prefix}-${random}`;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Check if an element matches a CSS selector
|
|
26
|
-
* @param element - The element to check
|
|
27
|
-
* @param selector - The CSS selector
|
|
28
|
-
* @returns True if the element matches
|
|
29
|
-
*/
|
|
30
|
-
export function matchesSelector(element, selector) {
|
|
31
|
-
return element.matches(selector);
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Find the closest ancestor matching a selector
|
|
35
|
-
* @param element - Starting element
|
|
36
|
-
* @param selector - CSS selector to match
|
|
37
|
-
* @returns The matching ancestor or null
|
|
38
|
-
*/
|
|
39
|
-
export function closestElement(element, selector) {
|
|
40
|
-
return element.closest(selector);
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Check if an element is visible in the viewport
|
|
44
|
-
* @param element - The element to check
|
|
45
|
-
* @param partial - Whether partial visibility counts
|
|
46
|
-
* @returns True if visible
|
|
47
|
-
*/
|
|
48
|
-
export function isElementVisible(element, partial = true) {
|
|
49
|
-
if (!isBrowser())
|
|
50
|
-
return false;
|
|
51
|
-
const rect = element.getBoundingClientRect();
|
|
52
|
-
const windowHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
53
|
-
const windowWidth = window.innerWidth || document.documentElement.clientWidth;
|
|
54
|
-
if (partial) {
|
|
55
|
-
return (rect.top < windowHeight &&
|
|
56
|
-
rect.bottom > 0 &&
|
|
57
|
-
rect.left < windowWidth &&
|
|
58
|
-
rect.right > 0);
|
|
59
|
-
}
|
|
60
|
-
return (rect.top >= 0 &&
|
|
61
|
-
rect.left >= 0 &&
|
|
62
|
-
rect.bottom <= windowHeight &&
|
|
63
|
-
rect.right <= windowWidth);
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Get all focusable elements within a container
|
|
67
|
-
* @param container - The container element
|
|
68
|
-
* @returns Array of focusable elements
|
|
69
|
-
*/
|
|
70
|
-
export function getFocusableElements(container) {
|
|
71
|
-
const focusableSelectors = [
|
|
72
|
-
'a[href]',
|
|
73
|
-
'area[href]',
|
|
74
|
-
'button:not([disabled])',
|
|
75
|
-
'input:not([disabled]):not([type="hidden"])',
|
|
76
|
-
'select:not([disabled])',
|
|
77
|
-
'textarea:not([disabled])',
|
|
78
|
-
'[tabindex]:not([tabindex="-1"])',
|
|
79
|
-
'[contenteditable="true"]'
|
|
80
|
-
].join(',');
|
|
81
|
-
return Array.from(container.querySelectorAll(focusableSelectors));
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Trap focus within a container (useful for modals)
|
|
85
|
-
* @param container - The container to trap focus in
|
|
86
|
-
* @returns Cleanup function to remove the trap
|
|
87
|
-
*/
|
|
88
|
-
export function trapFocus(container) {
|
|
89
|
-
const focusableElements = getFocusableElements(container);
|
|
90
|
-
const firstElement = focusableElements[0];
|
|
91
|
-
const lastElement = focusableElements[focusableElements.length - 1];
|
|
92
|
-
const handleKeyDown = (event) => {
|
|
93
|
-
if (event.key !== 'Tab')
|
|
94
|
-
return;
|
|
95
|
-
if (event.shiftKey) {
|
|
96
|
-
if (document.activeElement === firstElement) {
|
|
97
|
-
event.preventDefault();
|
|
98
|
-
lastElement?.focus();
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
if (document.activeElement === lastElement) {
|
|
103
|
-
event.preventDefault();
|
|
104
|
-
firstElement?.focus();
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
container.addEventListener('keydown', handleKeyDown);
|
|
109
|
-
firstElement?.focus();
|
|
110
|
-
return () => {
|
|
111
|
-
container.removeEventListener('keydown', handleKeyDown);
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Scroll an element into view smoothly
|
|
116
|
-
* @param element - The element to scroll to
|
|
117
|
-
* @param options - Scroll options
|
|
118
|
-
*/
|
|
119
|
-
export function scrollIntoView(element, options = { behavior: 'smooth', block: 'nearest' }) {
|
|
120
|
-
element.scrollIntoView(options);
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Get the scroll parent of an element
|
|
124
|
-
* @param element - The element to find scroll parent for
|
|
125
|
-
* @returns The scroll parent element
|
|
126
|
-
*/
|
|
127
|
-
export function getScrollParent(element) {
|
|
128
|
-
if (!isBrowser())
|
|
129
|
-
return null;
|
|
130
|
-
let parent = element.parentElement;
|
|
131
|
-
while (parent) {
|
|
132
|
-
const style = getComputedStyle(parent);
|
|
133
|
-
const overflow = style.overflow + style.overflowY + style.overflowX;
|
|
134
|
-
if (/auto|scroll|overlay/.test(overflow)) {
|
|
135
|
-
return parent;
|
|
136
|
-
}
|
|
137
|
-
parent = parent.parentElement;
|
|
138
|
-
}
|
|
139
|
-
return document.scrollingElement || document.documentElement;
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Disable body scroll (useful for modals)
|
|
143
|
-
* @returns Cleanup function to re-enable scroll
|
|
144
|
-
*/
|
|
145
|
-
export function disableBodyScroll() {
|
|
146
|
-
if (!isBrowser())
|
|
147
|
-
return () => { };
|
|
148
|
-
const scrollY = window.scrollY;
|
|
149
|
-
const body = document.body;
|
|
150
|
-
const originalStyles = {
|
|
151
|
-
position: body.style.position,
|
|
152
|
-
top: body.style.top,
|
|
153
|
-
width: body.style.width,
|
|
154
|
-
overflow: body.style.overflow
|
|
155
|
-
};
|
|
156
|
-
body.style.position = 'fixed';
|
|
157
|
-
body.style.top = `-${scrollY}px`;
|
|
158
|
-
body.style.width = '100%';
|
|
159
|
-
body.style.overflow = 'hidden';
|
|
160
|
-
return () => {
|
|
161
|
-
body.style.position = originalStyles.position;
|
|
162
|
-
body.style.top = originalStyles.top;
|
|
163
|
-
body.style.width = originalStyles.width;
|
|
164
|
-
body.style.overflow = originalStyles.overflow;
|
|
165
|
-
window.scrollTo(0, scrollY);
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Copy text to clipboard
|
|
170
|
-
* @param text - The text to copy
|
|
171
|
-
* @returns Promise that resolves when copied
|
|
172
|
-
*/
|
|
173
|
-
export async function copyToClipboard(text) {
|
|
174
|
-
if (!isBrowser()) {
|
|
175
|
-
throw new Error('Clipboard API not available in this environment');
|
|
176
|
-
}
|
|
177
|
-
if (navigator.clipboard && navigator.clipboard.writeText) {
|
|
178
|
-
await navigator.clipboard.writeText(text);
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
// Fallback for older browsers
|
|
182
|
-
const textArea = document.createElement('textarea');
|
|
183
|
-
textArea.value = text;
|
|
184
|
-
textArea.style.position = 'fixed';
|
|
185
|
-
textArea.style.left = '-9999px';
|
|
186
|
-
textArea.style.top = '-9999px';
|
|
187
|
-
document.body.appendChild(textArea);
|
|
188
|
-
textArea.focus();
|
|
189
|
-
textArea.select();
|
|
190
|
-
document.execCommand('copy');
|
|
191
|
-
document.body.removeChild(textArea);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Check if an element has a specific CSS class
|
|
196
|
-
* @param element - The element to check
|
|
197
|
-
* @param className - The class name
|
|
198
|
-
* @returns True if the element has the class
|
|
199
|
-
*/
|
|
200
|
-
export function hasClass(element, className) {
|
|
201
|
-
return element.classList.contains(className);
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Add CSS class(es) to an element
|
|
205
|
-
* @param element - The element to modify
|
|
206
|
-
* @param classNames - Class name(s) to add
|
|
207
|
-
*/
|
|
208
|
-
export function addClass(element, ...classNames) {
|
|
209
|
-
element.classList.add(...classNames);
|
|
210
|
-
}
|
|
211
|
-
/**
|
|
212
|
-
* Remove CSS class(es) from an element
|
|
213
|
-
* @param element - The element to modify
|
|
214
|
-
* @param classNames - Class name(s) to remove
|
|
215
|
-
*/
|
|
216
|
-
export function removeClass(element, ...classNames) {
|
|
217
|
-
element.classList.remove(...classNames);
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Toggle a CSS class on an element
|
|
221
|
-
* @param element - The element to modify
|
|
222
|
-
* @param className - The class name to toggle
|
|
223
|
-
* @param force - Optional force add (true) or remove (false)
|
|
224
|
-
* @returns True if the class is now present
|
|
225
|
-
*/
|
|
226
|
-
export function toggleClass(element, className, force) {
|
|
227
|
-
return element.classList.toggle(className, force);
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Get computed CSS property value
|
|
231
|
-
* @param element - The element to check
|
|
232
|
-
* @param property - CSS property name
|
|
233
|
-
* @returns The computed value
|
|
234
|
-
*/
|
|
235
|
-
export function getComputedStyleValue(element, property) {
|
|
236
|
-
if (!isBrowser())
|
|
237
|
-
return '';
|
|
238
|
-
return getComputedStyle(element).getPropertyValue(property);
|
|
239
|
-
}
|
|
240
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9tLnV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdWktY29tcG9uZW50cy9zcmMvbGliL3NoYXJlZC91dGlscy9kb20udXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztHQUdHO0FBRUg7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLFNBQVM7SUFDdkIsT0FBTyxPQUFPLE1BQU0sS0FBSyxXQUFXLElBQUksT0FBTyxRQUFRLEtBQUssV0FBVyxDQUFDO0FBQzFFLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxNQUFNO0lBQzlDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUMxRCxPQUFPLEdBQUcsTUFBTSxJQUFJLE1BQU0sRUFBRSxDQUFDO0FBQy9CLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsT0FBZ0IsRUFBRSxRQUFnQjtJQUNoRSxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7QUFDbkMsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FBb0IsT0FBZ0IsRUFBRSxRQUFnQjtJQUNsRixPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFhLENBQUM7QUFDL0MsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLGdCQUFnQixDQUFDLE9BQWdCLEVBQUUsT0FBTyxHQUFHLElBQUk7SUFDL0QsSUFBSSxDQUFDLFNBQVMsRUFBRTtRQUFFLE9BQU8sS0FBSyxDQUFDO0lBRS9CLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO0lBQzdDLE1BQU0sWUFBWSxH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LENBQUMsQ0FBQztBQUM5RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIERPTSB1dGlsaXR5IGZ1bmN0aW9ucyBmb3IgUEVDQiBVSSBDb21wb25lbnRzXHJcbiAqIEBtb2R1bGUgdXRpbHMvZG9tXHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIENoZWNrIGlmIGNvZGUgaXMgcnVubmluZyBpbiBhIGJyb3dzZXIgZW52aXJvbm1lbnRcclxuICogQHJldHVybnMgVHJ1ZSBpZiBydW5uaW5nIGluIGJyb3dzZXJcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBpc0Jyb3dzZXIoKTogYm9vbGVhbiB7XHJcbiAgcmV0dXJuIHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCc7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZW5lcmF0ZSBhIHVuaXF1ZSBJRCBmb3IgRE9NIGVsZW1lbnRzXHJcbiAqIEBwYXJhbSBwcmVmaXggLSBPcHRpb25hbCBwcmVmaXggZm9yIHRoZSBJRFxyXG4gKiBAcmV0dXJucyBBIHVuaXF1ZSBJRCBzdHJpbmdcclxuICpcclxuICogQGV4YW1wbGVcclxuICogZ2VuZXJhdGVVbmlxdWVJZCgnYnRuJykgLy8gJ2J0bi1hMWIyYzNkNCdcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVVuaXF1ZUlkKHByZWZpeCA9ICdwZWNiJyk6IHN0cmluZyB7XHJcbiAgY29uc3QgcmFuZG9tID0gTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyaW5nKDIsIDkpO1xyXG4gIHJldHVybiBgJHtwcmVmaXh9LSR7cmFuZG9tfWA7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVjayBpZiBhbiBlbGVtZW50IG1hdGNoZXMgYSBDU1Mgc2VsZWN0b3JcclxuICogQHBhcmFtIGVsZW1lbnQgLSBUaGUgZWxlbWVudCB0byBjaGVja1xyXG4gKiBAcGFyYW0gc2VsZWN0b3IgLSBUaGUgQ1NTIHNlbGVjdG9yXHJcbiAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGVsZW1lbnQgbWF0Y2hlc1xyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIG1hdGNoZXNTZWxlY3RvcihlbGVtZW50OiBFbGVtZW50LCBzZWxlY3Rvcjogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgcmV0dXJuIGVsZW1lbnQubWF0Y2hlcyhzZWxlY3Rvcik7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBGaW5kIHRoZSBjbG9zZXN0IGFuY2VzdG9yIG1hdGNoaW5nIGEgc2VsZWN0b3JcclxuICogQHBhcmFtIGVsZW1lbnQgLSBTdGFydGluZyBlbGVtZW50XHJcbiAqIEBwYXJhbSBzZWxlY3RvciAtIENTUyBzZWxlY3RvciB0byBtYXRjaFxyXG4gKiBAcmV0dXJucyBUaGUgbWF0Y2hpbmcgYW5jZXN0b3Igb3IgbnVsbFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGNsb3Nlc3RFbGVtZW50PFQgZXh0ZW5kcyBFbGVtZW50PihlbGVtZW50OiBFbGVtZW50LCBzZWxlY3Rvcjogc3RyaW5nKTogVCB8IG51bGwge1xyXG4gIHJldHVybiBlbGVtZW50LmNsb3Nlc3Qoc2VsZWN0b3IpIGFzIFQgfCBudWxsO1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2sgaWYgYW4gZWxlbWVudCBpcyB2aXNpYmxlIGluIHRoZSB2aWV3cG9ydFxyXG4gKiBAcGFyYW0gZWxlbWVudCAtIFRoZSBlbGVtZW50IHRvIGNoZWNrXHJcbiAqIEBwYXJhbSBwYXJ0aWFsIC0gV2hldGhlciBwYXJ0aWFsIHZpc2liaWxpdHkgY291bnRzXHJcbiAqIEByZXR1cm5zIFRydWUgaWYgdmlzaWJsZVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGlzRWxlbWVudFZpc2libGUoZWxlbWVudDogRWxlbWVudCwgcGFydGlhbCA9IHRydWUpOiBib29sZWFuIHtcclxuICBpZiAoIWlzQnJvd3NlcigpKSByZXR1cm4gZmFsc2U7XHJcblxyXG4gIGNvbnN0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gIGNvbnN0IHdpbmRvd0hlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0O1xyXG4gIGNvbnN0IHdpbmRvd1dpZHRoID0gd2luZG93LmlubmVyV2lkdGggfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoO1xyXG5cclxuICBpZiAocGFydGlhbCkge1xyXG4gICAgcmV0dXJuIChcclxuICAgICAgcmVjdC50b3AgPCB3aW5kb3dIZWlnaHQgJiZcclxuICAgICAgcmVjdC5ib3R0b20gPiAwICYmXHJcbiAgICAgIHJlY3QubGVmdCA8IHdpbmRvd1dpZHRoICYmXHJcbiAgICAgIHJlY3QucmlnaHQgPiAwXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIChcclxuICAgIHJlY3QudG9wID49IDAgJiZcclxuICAgIHJlY3QubGVmdCA+PSAwICYmXHJcbiAgICByZWN0LmJvdHRvbSA8PSB3aW5kb3dIZWlnaHQgJiZcclxuICAgIHJlY3QucmlnaHQgPD0gd2luZG93V2lkdGhcclxuICApO1xyXG59XHJcblxyXG4vKipcclxuICogR2V0IGFsbCBmb2N1c2FibGUgZWxlbWVudHMgd2l0aGluIGEgY29udGFpbmVyXHJcbiAqIEBwYXJhbSBjb250YWluZXIgLSBUaGUgY29udGFpbmVyIGVsZW1lbnRcclxuICogQHJldHVybnMgQXJyYXkgb2YgZm9jdXNhYmxlIGVsZW1lbnRzXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9jdXNhYmxlRWxlbWVudHMoY29udGFpbmVyOiBFbGVtZW50KTogSFRNTEVsZW1lbnRbXSB7XHJcbiAgY29uc3QgZm9jdXNhYmxlU2VsZWN0b3JzID0gW1xyXG4gICAgJ2FbaHJlZl0nLFxyXG4gICAgJ2FyZWFbaHJlZl0nLFxyXG4gICAgJ2J1dHRvbjpub3QoW2Rpc2FibGVkXSknLFxyXG4gICAgJ2lucHV0Om5vdChbZGlzYWJsZWRdKTpub3QoW3R5cGU9XCJoaWRkZW5cIl0pJyxcclxuICAgICdzZWxlY3Q6bm90KFtkaXNhYmxlZF0pJyxcclxuICAgICd0ZXh0YXJlYTpub3QoW2Rpc2FibGVkXSknLFxyXG4gICAgJ1t0YWJpbmRleF06bm90KFt0YWJpbmRleD1cIi0xXCJdKScsXHJcbiAgICAnW2NvbnRlbnRlZGl0YWJsZT1cInRydWVcIl0nXHJcbiAgXS5qb2luKCcsJyk7XHJcblxyXG4gIHJldHVybiBBcnJheS5mcm9tKGNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsPEhUTUxFbGVtZW50Pihmb2N1c2FibGVTZWxlY3RvcnMpKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFRyYXAgZm9jdXMgd2l0aGluIGEgY29udGFpbmVyICh1c2VmdWwgZm9yIG1vZGFscylcclxuICogQHBhcmFtIGNvbnRhaW5lciAtIFRoZSBjb250YWluZXIgdG8gdHJhcCBmb2N1cyBpblxyXG4gKiBAcmV0dXJucyBDbGVhbnVwIGZ1bmN0aW9uIHRvIHJlbW92ZSB0aGUgdHJhcFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHRyYXBGb2N1cyhjb250YWluZXI6IEhUTUxFbGVtZW50KTogKCkgPT4gdm9pZCB7XHJcbiAgY29uc3QgZm9jdXNhYmxlRWxlbWVudHMgPSBnZXRGb2N1c2FibGVFbGVtZW50cyhjb250YWluZXIpO1xyXG4gIGNvbnN0IGZpcnN0RWxlbWVudCA9IGZvY3VzYWJsZUVsZW1lbnRzWzBdO1xyXG4gIGNvbnN0IGxhc3RFbGVtZW50ID0gZm9jdXNhYmxlRWxlbWVudHNbZm9jdXNhYmxlRWxlbWVudHMubGVuZ3RoIC0gMV07XHJcblxyXG4gIGNvbnN0IGhhbmRsZUtleURvd24gPSAoZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkID0+IHtcclxuICAgIGlmIChldmVudC5rZXkgIT09ICdUYWInKSByZXR1cm47XHJcblxyXG4gICAgaWYgKGV2ZW50LnNoaWZ0S2V5KSB7XHJcbiAgICAgIGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50ID09PSBmaXJzdEVsZW1lbnQpIHtcclxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIGxhc3RFbGVtZW50Py5mb2N1cygpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAoZG9jdW1lbnQuYWN0aXZlRWxlbWVudCA9PT0gbGFzdEVsZW1lbnQpIHtcclxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIGZpcnN0RWxlbWVudD8uZm9jdXMoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIGNvbnRhaW5lci5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgaGFuZGxlS2V5RG93bik7XHJcbiAgZmlyc3RFbGVtZW50Py5mb2N1cygpO1xyXG5cclxuICByZXR1cm4gKCkgPT4ge1xyXG4gICAgY29udGFpbmVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBoYW5kbGVLZXlEb3duKTtcclxuICB9O1xyXG59XHJcblxyXG4vKipcclxuICogU2Nyb2xsIGFuIGVsZW1lbnQgaW50byB2aWV3IHNtb290aGx5XHJcbiAqIEBwYXJhbSBlbGVtZW50IC0gVGhlIGVsZW1lbnQgdG8gc2Nyb2xsIHRvXHJcbiAqIEBwYXJhbSBvcHRpb25zIC0gU2Nyb2xsIG9wdGlvbnNcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBzY3JvbGxJbnRvVmlldyhcclxuICBlbGVtZW50OiBFbGVtZW50LFxyXG4gIG9wdGlvbnM6IFNjcm9sbEludG9WaWV3T3B0aW9ucyA9IHsgYmVoYXZpb3I6ICdzbW9vdGgnLCBibG9jazogJ25lYXJlc3QnIH1cclxuKTogdm9pZCB7XHJcbiAgZWxlbWVudC5zY3JvbGxJbnRvVmlldyhvcHRpb25zKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCB0aGUgc2Nyb2xsIHBhcmVudCBvZiBhbiBlbGVtZW50XHJcbiAqIEBwYXJhbSBlbGVtZW50IC0gVGhlIGVsZW1lbnQgdG8gZmluZCBzY3JvbGwgcGFyZW50IGZvclxyXG4gKiBAcmV0dXJucyBUaGUgc2Nyb2xsIHBhcmVudCBlbGVtZW50XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2Nyb2xsUGFyZW50KGVsZW1lbnQ6IEVsZW1lbnQpOiBFbGVtZW50IHwgbnVsbCB7XHJcbiAgaWYgKCFpc0Jyb3dzZXIoKSkgcmV0dXJuIG51bGw7XHJcblxyXG4gIGxldCBwYXJlbnQ6IEVsZW1lbnQgfCBudWxsID0gZWxlbWVudC5wYXJlbnRFbGVtZW50O1xyXG5cclxuICB3aGlsZSAocGFyZW50KSB7XHJcbiAgICBjb25zdCBzdHlsZSA9IGdldENvbXB1dGVkU3R5bGUocGFyZW50KTtcclxuICAgIGNvbnN0IG92ZXJmbG93ID0gc3R5bGUub3ZlcmZsb3cgKyBzdHlsZS5vdmVyZmxvd1kgKyBzdHlsZS5vdmVyZmxvd1g7XHJcblxyXG4gICAgaWYgKC9hdXRvfHNjcm9sbHxvdmVybGF5Ly50ZXN0KG92ZXJmbG93KSkge1xyXG4gICAgICByZXR1cm4gcGFyZW50O1xyXG4gICAgfVxyXG5cclxuICAgIHBhcmVudCA9IHBhcmVudC5wYXJlbnRFbGVtZW50O1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xyXG59XHJcblxyXG4vKipcclxuICogRGlzYWJsZSBib2R5IHNjcm9sbCAodXNlZnVsIGZvciBtb2RhbHMpXHJcbiAqIEByZXR1cm5zIENsZWFudXAgZnVuY3Rpb24gdG8gcmUtZW5hYmxlIHNjcm9sbFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGRpc2FibGVCb2R5U2Nyb2xsKCk6ICgpID0+IHZvaWQge1xyXG4gIGlmICghaXNCcm93c2VyKCkpIHJldHVybiAoKSA9PiB7fTtcclxuXHJcbiAgY29uc3Qgc2Nyb2xsWSA9IHdpbmRvdy5zY3JvbGxZO1xyXG4gIGNvbnN0IGJvZHkgPSBkb2N1bWVudC5ib2R5O1xyXG4gIGNvbnN0IG9yaWdpbmFsU3R5bGVzID0ge1xyXG4gICAgcG9zaXRpb246IGJvZHkuc3R5bGUucG9zaXRpb24sXHJcbiAgICB0b3A6IGJvZHkuc3R5bGUudG9wLFxyXG4gICAgd2lkdGg6IGJvZHkuc3R5bGUud2lkdGgsXHJcbiAgICBvdmVyZmxvdzogYm9keS5zdHlsZS5vdmVyZmxvd1xyXG4gIH07XHJcblxyXG4gIGJvZHkuc3R5bGUucG9zaXRpb24gPSAnZml4ZWQnO1xyXG4gIGJvZHkuc3R5bGUudG9wID0gYC0ke3Njcm9sbFl9cHhgO1xyXG4gIGJvZHkuc3R5bGUud2lkdGggPSAnMTAwJSc7XHJcbiAgYm9keS5zdHlsZS5vdmVyZmxvdyA9ICdoaWRkZW4nO1xyXG5cclxuICByZXR1cm4gKCkgPT4ge1xyXG4gICAgYm9keS5zdHlsZS5wb3NpdGlvbiA9IG9yaWdpbmFsU3R5bGVzLnBvc2l0aW9uO1xyXG4gICAgYm9keS5zdHlsZS50b3AgPSBvcmlnaW5hbFN0eWxlcy50b3A7XHJcbiAgICBib2R5LnN0eWxlLndpZHRoID0gb3JpZ2luYWxTdHlsZXMud2lkdGg7XHJcbiAgICBib2R5LnN0eWxlLm92ZXJmbG93ID0gb3JpZ2luYWxTdHlsZXMub3ZlcmZsb3c7XHJcbiAgICB3aW5kb3cuc2Nyb2xsVG8oMCwgc2Nyb2xsWSk7XHJcbiAgfTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENvcHkgdGV4dCB0byBjbGlwYm9hcmRcclxuICogQHBhcmFtIHRleHQgLSBUaGUgdGV4dCB0byBjb3B5XHJcbiAqIEByZXR1cm5zIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIGNvcGllZFxyXG4gKi9cclxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvcHlUb0NsaXBib2FyZCh0ZXh0OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICBpZiAoIWlzQnJvd3NlcigpKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0NsaXBib2FyZCBBUEkgbm90IGF2YWlsYWJsZSBpbiB0aGlzIGVudmlyb25tZW50Jyk7XHJcbiAgfVxyXG5cclxuICBpZiAobmF2aWdhdG9yLmNsaXBib2FyZCAmJiBuYXZpZ2F0b3IuY2xpcGJvYXJkLndyaXRlVGV4dCkge1xyXG4gICAgYXdhaXQgbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQodGV4dCk7XHJcbiAgfSBlbHNlIHtcclxuICAgIC8vIEZhbGxiYWNrIGZvciBvbGRlciBicm93c2Vyc1xyXG4gICAgY29uc3QgdGV4dEFyZWEgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0ZXh0YXJlYScpO1xyXG4gICAgdGV4dEFyZWEudmFsdWUgPSB0ZXh0O1xyXG4gICAgdGV4dEFyZWEuc3R5bGUucG9zaXRpb24gPSAnZml4ZWQnO1xyXG4gICAgdGV4dEFyZWEuc3R5bGUubGVmdCA9ICctOTk5OXB4JztcclxuICAgIHRleHRBcmVhLnN0eWxlLnRvcCA9ICctOTk5OXB4JztcclxuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQodGV4dEFyZWEpO1xyXG4gICAgdGV4dEFyZWEuZm9jdXMoKTtcclxuICAgIHRleHRBcmVhLnNlbGVjdCgpO1xyXG4gICAgZG9jdW1lbnQuZXhlY0NvbW1hbmQoJ2NvcHknKTtcclxuICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQodGV4dEFyZWEpO1xyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIENoZWNrIGlmIGFuIGVsZW1lbnQgaGFzIGEgc3BlY2lmaWMgQ1NTIGNsYXNzXHJcbiAqIEBwYXJhbSBlbGVtZW50IC0gVGhlIGVsZW1lbnQgdG8gY2hlY2tcclxuICogQHBhcmFtIGNsYXNzTmFtZSAtIFRoZSBjbGFzcyBuYW1lXHJcbiAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGVsZW1lbnQgaGFzIHRoZSBjbGFzc1xyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGhhc0NsYXNzKGVsZW1lbnQ6IEVsZW1lbnQsIGNsYXNzTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgcmV0dXJuIGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKGNsYXNzTmFtZSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBZGQgQ1NTIGNsYXNzKGVzKSB0byBhbiBlbGVtZW50XHJcbiAqIEBwYXJhbSBlbGVtZW50IC0gVGhlIGVsZW1lbnQgdG8gbW9kaWZ5XHJcbiAqIEBwYXJhbSBjbGFzc05hbWVzIC0gQ2xhc3MgbmFtZShzKSB0byBhZGRcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBhZGRDbGFzcyhlbGVtZW50OiBFbGVtZW50LCAuLi5jbGFzc05hbWVzOiBzdHJpbmdbXSk6IHZvaWQge1xyXG4gIGVsZW1lbnQuY2xhc3NMaXN0LmFkZCguLi5jbGFzc05hbWVzKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJlbW92ZSBDU1MgY2xhc3MoZXMpIGZyb20gYW4gZWxlbWVudFxyXG4gKiBAcGFyYW0gZWxlbWVudCAtIFRoZSBlbGVtZW50IHRvIG1vZGlmeVxyXG4gKiBAcGFyYW0gY2xhc3NOYW1lcyAtIENsYXNzIG5hbWUocykgdG8gcmVtb3ZlXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlQ2xhc3MoZWxlbWVudDogRWxlbWVudCwgLi4uY2xhc3NOYW1lczogc3RyaW5nW10pOiB2b2lkIHtcclxuICBlbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoLi4uY2xhc3NOYW1lcyk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBUb2dnbGUgYSBDU1MgY2xhc3Mgb24gYW4gZWxlbWVudFxyXG4gKiBAcGFyYW0gZWxlbWVudCAtIFRoZSBlbGVtZW50IHRvIG1vZGlmeVxyXG4gKiBAcGFyYW0gY2xhc3NOYW1lIC0gVGhlIGNsYXNzIG5hbWUgdG8gdG9nZ2xlXHJcbiAqIEBwYXJhbSBmb3JjZSAtIE9wdGlvbmFsIGZvcmNlIGFkZCAodHJ1ZSkgb3IgcmVtb3ZlIChmYWxzZSlcclxuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgY2xhc3MgaXMgbm93IHByZXNlbnRcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiB0b2dnbGVDbGFzcyhlbGVtZW50OiBFbGVtZW50LCBjbGFzc05hbWU6IHN0cmluZywgZm9yY2U/OiBib29sZWFuKTogYm9vbGVhbiB7XHJcbiAgcmV0dXJuIGVsZW1lbnQuY2xhc3NMaXN0LnRvZ2dsZShjbGFzc05hbWUsIGZvcmNlKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCBjb21wdXRlZCBDU1MgcHJvcGVydHkgdmFsdWVcclxuICogQHBhcmFtIGVsZW1lbnQgLSBUaGUgZWxlbWVudCB0byBjaGVja1xyXG4gKiBAcGFyYW0gcHJvcGVydHkgLSBDU1MgcHJvcGVydHkgbmFtZVxyXG4gKiBAcmV0dXJucyBUaGUgY29tcHV0ZWQgdmFsdWVcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRDb21wdXRlZFN0eWxlVmFsdWUoZWxlbWVudDogRWxlbWVudCwgcHJvcGVydHk6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgaWYgKCFpc0Jyb3dzZXIoKSkgcmV0dXJuICcnO1xyXG4gIHJldHVybiBnZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpLmdldFByb3BlcnR5VmFsdWUocHJvcGVydHkpO1xyXG59XHJcbiJdfQ==
|
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Error handling utility functions for PECB UI Components
|
|
3
|
-
* Provides standardized error handling patterns
|
|
4
|
-
* @module utils/error
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Create a standardized PECB error
|
|
8
|
-
* @param message - Error message
|
|
9
|
-
* @param options - Additional error options
|
|
10
|
-
* @returns A standardized PecbError object
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* const error = createError('Invalid input', {
|
|
14
|
-
* code: 'VALIDATION_001',
|
|
15
|
-
* category: 'validation',
|
|
16
|
-
* severity: 'warning',
|
|
17
|
-
* recoverable: true
|
|
18
|
-
* });
|
|
19
|
-
*/
|
|
20
|
-
export function createError(message, options = {}) {
|
|
21
|
-
return {
|
|
22
|
-
code: options.code ?? 'PECB_ERROR',
|
|
23
|
-
message,
|
|
24
|
-
severity: options.severity ?? 'error',
|
|
25
|
-
category: options.category ?? 'unknown',
|
|
26
|
-
originalError: options.originalError,
|
|
27
|
-
context: options.context,
|
|
28
|
-
timestamp: new Date(),
|
|
29
|
-
recoveryAction: options.recoveryAction,
|
|
30
|
-
recoverable: options.recoverable ?? false
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Create a validation error
|
|
35
|
-
* @param field - Field name that failed validation
|
|
36
|
-
* @param rule - Validation rule that failed
|
|
37
|
-
* @param message - Error message
|
|
38
|
-
* @returns A ValidationError object
|
|
39
|
-
*
|
|
40
|
-
* @example
|
|
41
|
-
* const error = createValidationError('email', 'format', 'Invalid email format');
|
|
42
|
-
*/
|
|
43
|
-
export function createValidationError(field, rule, message, details) {
|
|
44
|
-
return {
|
|
45
|
-
field,
|
|
46
|
-
rule,
|
|
47
|
-
message,
|
|
48
|
-
expected: details?.expected,
|
|
49
|
-
actual: details?.actual
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Wrap an unknown error in a PecbError
|
|
54
|
-
* @param error - The error to wrap
|
|
55
|
-
* @param options - Additional options
|
|
56
|
-
* @returns A standardized PecbError
|
|
57
|
-
*
|
|
58
|
-
* @example
|
|
59
|
-
* try {
|
|
60
|
-
* await riskyOperation();
|
|
61
|
-
* } catch (e) {
|
|
62
|
-
* const error = wrapError(e, { category: 'network' });
|
|
63
|
-
* handleError(error);
|
|
64
|
-
* }
|
|
65
|
-
*/
|
|
66
|
-
export function wrapError(error, options = {}) {
|
|
67
|
-
if (isPecbError(error)) {
|
|
68
|
-
return error;
|
|
69
|
-
}
|
|
70
|
-
let message = 'An unknown error occurred';
|
|
71
|
-
let originalError;
|
|
72
|
-
if (error instanceof Error) {
|
|
73
|
-
message = error.message;
|
|
74
|
-
originalError = error;
|
|
75
|
-
}
|
|
76
|
-
else if (typeof error === 'string') {
|
|
77
|
-
message = error;
|
|
78
|
-
}
|
|
79
|
-
else if (error && typeof error === 'object' && 'message' in error) {
|
|
80
|
-
message = String(error.message);
|
|
81
|
-
}
|
|
82
|
-
return createError(message, {
|
|
83
|
-
...options,
|
|
84
|
-
originalError
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Type guard to check if an object is a PecbError
|
|
89
|
-
* @param error - The object to check
|
|
90
|
-
* @returns True if the object is a PecbError
|
|
91
|
-
*/
|
|
92
|
-
export function isPecbError(error) {
|
|
93
|
-
return (error !== null &&
|
|
94
|
-
typeof error === 'object' &&
|
|
95
|
-
'code' in error &&
|
|
96
|
-
'message' in error &&
|
|
97
|
-
'severity' in error &&
|
|
98
|
-
'category' in error &&
|
|
99
|
-
'timestamp' in error);
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Type guard to check if an error is recoverable
|
|
103
|
-
* @param error - The error to check
|
|
104
|
-
* @returns True if the error is recoverable
|
|
105
|
-
*/
|
|
106
|
-
export function isRecoverableError(error) {
|
|
107
|
-
return error.recoverable;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Format an error for display to users
|
|
111
|
-
* @param error - The error to format
|
|
112
|
-
* @param includeCode - Whether to include the error code
|
|
113
|
-
* @returns Formatted error message
|
|
114
|
-
*/
|
|
115
|
-
export function formatErrorMessage(error, includeCode = false) {
|
|
116
|
-
if (includeCode) {
|
|
117
|
-
return `[${error.code}] ${error.message}`;
|
|
118
|
-
}
|
|
119
|
-
return error.message;
|
|
120
|
-
}
|
|
121
|
-
/**
|
|
122
|
-
* Format an error for logging
|
|
123
|
-
* @param error - The error to format
|
|
124
|
-
* @returns Formatted error string for logging
|
|
125
|
-
*/
|
|
126
|
-
export function formatErrorForLog(error) {
|
|
127
|
-
const parts = [
|
|
128
|
-
`[${error.timestamp.toISOString()}]`,
|
|
129
|
-
`[${error.severity.toUpperCase()}]`,
|
|
130
|
-
`[${error.code}]`,
|
|
131
|
-
error.message
|
|
132
|
-
];
|
|
133
|
-
if (error.context) {
|
|
134
|
-
parts.push(`Context: ${JSON.stringify(error.context)}`);
|
|
135
|
-
}
|
|
136
|
-
if (error.originalError?.stack) {
|
|
137
|
-
parts.push(`Stack: ${error.originalError.stack}`);
|
|
138
|
-
}
|
|
139
|
-
return parts.join(' ');
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Create a network error
|
|
143
|
-
* @param message - Error message
|
|
144
|
-
* @param statusCode - HTTP status code if applicable
|
|
145
|
-
* @param originalError - Original error
|
|
146
|
-
* @returns A network category PecbError
|
|
147
|
-
*/
|
|
148
|
-
export function createNetworkError(message, statusCode, originalError) {
|
|
149
|
-
return createError(message, {
|
|
150
|
-
code: statusCode ? `NETWORK_${statusCode}` : 'NETWORK_ERROR',
|
|
151
|
-
category: 'network',
|
|
152
|
-
severity: 'error',
|
|
153
|
-
context: statusCode ? { statusCode } : undefined,
|
|
154
|
-
recoverable: true,
|
|
155
|
-
recoveryAction: 'Please check your connection and try again',
|
|
156
|
-
originalError
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Create an authentication error
|
|
161
|
-
* @param message - Error message
|
|
162
|
-
* @param originalError - Original error
|
|
163
|
-
* @returns An authentication category PecbError
|
|
164
|
-
*/
|
|
165
|
-
export function createAuthError(message, originalError) {
|
|
166
|
-
return createError(message, {
|
|
167
|
-
code: 'AUTH_ERROR',
|
|
168
|
-
category: 'authentication',
|
|
169
|
-
severity: 'error',
|
|
170
|
-
recoverable: true,
|
|
171
|
-
recoveryAction: 'Please sign in again',
|
|
172
|
-
originalError
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Create an authorization error
|
|
177
|
-
* @param message - Error message
|
|
178
|
-
* @param resource - The resource that access was denied to
|
|
179
|
-
* @returns An authorization category PecbError
|
|
180
|
-
*/
|
|
181
|
-
export function createAuthorizationError(message, resource) {
|
|
182
|
-
return createError(message, {
|
|
183
|
-
code: 'AUTHZ_ERROR',
|
|
184
|
-
category: 'authorization',
|
|
185
|
-
severity: 'warning',
|
|
186
|
-
context: resource ? { resource } : undefined,
|
|
187
|
-
recoverable: false,
|
|
188
|
-
recoveryAction: 'Contact an administrator for access'
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
/**
|
|
192
|
-
* Create a configuration error
|
|
193
|
-
* @param message - Error message
|
|
194
|
-
* @param configKey - The configuration key that is invalid
|
|
195
|
-
* @returns A configuration category PecbError
|
|
196
|
-
*/
|
|
197
|
-
export function createConfigError(message, configKey) {
|
|
198
|
-
return createError(message, {
|
|
199
|
-
code: 'CONFIG_ERROR',
|
|
200
|
-
category: 'configuration',
|
|
201
|
-
severity: 'critical',
|
|
202
|
-
context: configKey ? { configKey } : undefined,
|
|
203
|
-
recoverable: false,
|
|
204
|
-
recoveryAction: 'Check your configuration settings'
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Global error handler registry
|
|
209
|
-
*/
|
|
210
|
-
const errorHandlers = new Map();
|
|
211
|
-
/**
|
|
212
|
-
* Register an error handler for a category
|
|
213
|
-
* @param category - The error category to handle
|
|
214
|
-
* @param handler - The handler function
|
|
215
|
-
* @returns Cleanup function to unregister
|
|
216
|
-
*/
|
|
217
|
-
export function registerErrorHandler(category, handler) {
|
|
218
|
-
const handlers = errorHandlers.get(category) ?? [];
|
|
219
|
-
handlers.push(handler);
|
|
220
|
-
errorHandlers.set(category, handlers);
|
|
221
|
-
return () => {
|
|
222
|
-
const currentHandlers = errorHandlers.get(category);
|
|
223
|
-
if (currentHandlers) {
|
|
224
|
-
const index = currentHandlers.indexOf(handler);
|
|
225
|
-
if (index > -1) {
|
|
226
|
-
currentHandlers.splice(index, 1);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* Handle an error by invoking registered handlers
|
|
233
|
-
* @param error - The error to handle
|
|
234
|
-
*/
|
|
235
|
-
export function handleError(error) {
|
|
236
|
-
const handlers = errorHandlers.get(error.category) ?? [];
|
|
237
|
-
const globalHandlers = errorHandlers.get('unknown') ?? [];
|
|
238
|
-
[...handlers, ...globalHandlers].forEach(handler => {
|
|
239
|
-
try {
|
|
240
|
-
handler(error);
|
|
241
|
-
}
|
|
242
|
-
catch (e) {
|
|
243
|
-
console.error('Error in error handler:', e);
|
|
244
|
-
}
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
/**
|
|
248
|
-
* Try to execute an operation and return a result or error
|
|
249
|
-
* @param operation - The operation to execute
|
|
250
|
-
* @param errorOptions - Options for error wrapping
|
|
251
|
-
* @returns A tuple of [result, null] or [null, error]
|
|
252
|
-
*/
|
|
253
|
-
export async function tryAsync(operation, errorOptions) {
|
|
254
|
-
try {
|
|
255
|
-
const result = await operation();
|
|
256
|
-
return [result, null];
|
|
257
|
-
}
|
|
258
|
-
catch (e) {
|
|
259
|
-
return [null, wrapError(e, errorOptions)];
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
/**
|
|
263
|
-
* Synchronous version of tryAsync
|
|
264
|
-
* @param operation - The operation to execute
|
|
265
|
-
* @param errorOptions - Options for error wrapping
|
|
266
|
-
* @returns A tuple of [result, null] or [null, error]
|
|
267
|
-
*/
|
|
268
|
-
export function trySync(operation, errorOptions) {
|
|
269
|
-
try {
|
|
270
|
-
const result = operation();
|
|
271
|
-
return [result, null];
|
|
272
|
-
}
|
|
273
|
-
catch (e) {
|
|
274
|
-
return [null, wrapError(e, errorOptions)];
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3IudXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aS1jb21wb25lbnRzL3NyYy9saWIvc2hhcmVkL3V0aWxzL2Vycm9yLnV0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUF3RUg7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUNILE1BQU0sVUFBVSxXQUFXLENBQUMsT0FBZSxFQUFFLFVBQXdCLEVBQUU7SUFDckUsT0FBTztRQUNMLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxJQUFJLFlBQVk7UUFDbEMsT0FBTztRQUNQLFFBQVEsRUFBRSxPQUFPLENBQUMsUUFBUSxJQUFJLE9BQU87UUFDckMsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRLElBQUksU0FBUztRQUN2QyxhQUFhLEVBQUUsT0FBTyxDQUFDLGFBQWE7UUFDcEMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO1FBQ3hCLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRTtRQUNyQixjQUFjLEVBQUUsT0FBTyxDQUFDLGNBQWM7UUFDdEMsV0FBVyxFQUFFLE9BQU8sQ0FBQyxXQUFXLElBQUksS0FBSztLQUMxQyxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSxxQkFBcUIsQ0FDbkMsS0FBYSxFQUNiLElBQVksRUFDWixPQUFlLEVBQ2YsT0FBaUQ7SUFFakQsT0FBTztRQUNMLEtBQUs7UUFDTCxJQUFJO1FBQ0osT0FBTztRQUNQLFFBQVEsRUFBRSxPQUFPLEVBQUUsUUFBUTtRQUMzQixNQUFNLEVBQUUsT0FBTyxFQUFFLE1BQU07S0FDeEIsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBTSxVQUFVLFNBQVMsQ0FBQyxLQUFjLEVBQUUsVUFBd0IsRUFBRTtJQUNsRSxJQUFJLFdBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3ZCLE9B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QUFDLEVBQUUsQ0FBQztZQUNYLE9BQU8sQ0FBQyxLQUFLLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDOUMsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxRQUFRLENBQzVCLFNBQTJCLEVBQzNCLFlBQTJCO0lBRTNCLElBQUksQ0FBQztRQUNILE1BQU0sTUFBTSxHQUFHLE1BQU0sU0FBUyxFQUFFLENBQUM7UUFDakMsT0FBTyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUN4QixDQUFDO0lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUNYLE9BQU8sQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUMsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDO0lBQzVDLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsT0FBTyxDQUNyQixTQUFrQixFQUNsQixZQUEyQjtJQUUzQixJQUFJLENBQUM7UUFDSCxNQUFNLE1BQU0sR0FBRyxTQUFTLEVBQUUsQ0FBQztRQUMzQixPQUFPLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3hCLENBQUM7SUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1FBQ1gsT0FBTyxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7SUFDNUMsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogRXJyb3IgaGFuZGxpbmcgdXRpbGl0eSBmdW5jdGlvbnMgZm9yIFBFQ0IgVUkgQ29tcG9uZW50c1xyXG4gKiBQcm92aWRlcyBzdGFuZGFyZGl6ZWQgZXJyb3IgaGFuZGxpbmcgcGF0dGVybnNcclxuICogQG1vZHVsZSB1dGlscy9lcnJvclxyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBFcnJvciBzZXZlcml0eSBsZXZlbHNcclxuICovXHJcbmV4cG9ydCB0eXBlIEVycm9yU2V2ZXJpdHkgPSAnaW5mbycgfCAnd2FybmluZycgfCAnZXJyb3InIHwgJ2NyaXRpY2FsJztcclxuXHJcbi8qKlxyXG4gKiBFcnJvciBjYXRlZ29yaWVzIGZvciBjbGFzc2lmaWNhdGlvblxyXG4gKi9cclxuZXhwb3J0IHR5cGUgRXJyb3JDYXRlZ29yeSA9XHJcbiAgfCAndmFsaWRhdGlvbidcclxuICB8ICduZXR3b3JrJ1xyXG4gIHwgJ2F1dGhlbnRpY2F0aW9uJ1xyXG4gIHwgJ2F1dGhvcml6YXRpb24nXHJcbiAgfCAnY29uZmlndXJhdGlvbidcclxuICB8ICdydW50aW1lJ1xyXG4gIHwgJ3Vua25vd24nO1xyXG5cclxuLyoqXHJcbiAqIFN0YW5kYXJkIGVycm9yIGludGVyZmFjZSBmb3IgUEVDQiBjb21wb25lbnRzXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIFBlY2JFcnJvciB7XHJcbiAgLyoqIFVuaXF1ZSBlcnJvciBjb2RlICovXHJcbiAgY29kZTogc3RyaW5nO1xyXG4gIC8qKiBIdW1hbi1yZWFkYWJsZSBlcnJvciBtZXNzYWdlICovXHJcbiAgbWVzc2FnZTogc3RyaW5nO1xyXG4gIC8qKiBFcnJvciBzZXZlcml0eSBsZXZlbCAqL1xyXG4gIHNldmVyaXR5OiBFcnJvclNldmVyaXR5O1xyXG4gIC8qKiBFcnJvciBjYXRlZ29yeSAqL1xyXG4gIGNhdGVnb3J5OiBFcnJvckNhdGVnb3J5O1xyXG4gIC8qKiBPcmlnaW5hbCBlcnJvciBpZiB3cmFwcGluZyBhbm90aGVyIGVycm9yICovXHJcbiAgb3JpZ2luYWxFcnJvcj86IEVycm9yO1xyXG4gIC8qKiBBZGRpdGlvbmFsIGNvbnRleHQgZGF0YSAqL1xyXG4gIGNvbnRleHQ/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcclxuICAvKiogVGltZXN0YW1wIHdoZW4gZXJyb3Igb2NjdXJyZWQgKi9cclxuICB0aW1lc3RhbXA6IERhdGU7XHJcbiAgLyoqIFN1Z2dlc3RlZCByZWNvdmVyeSBhY3Rpb24gKi9cclxuICByZWNvdmVyeUFjdGlvbj86IHN0cmluZztcclxuICAvKiogV2hldGhlciB0aGUgZXJyb3IgaXMgcmVjb3ZlcmFibGUgKi9cclxuICByZWNvdmVyYWJsZTogYm9vbGVhbjtcclxufVxyXG5cclxuLyoqXHJcbiAqIFZhbGlkYXRpb24gZXJyb3IgZGV0YWlsc1xyXG4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0aW9uRXJyb3Ige1xyXG4gIC8qKiBGaWVsZCBuYW1lIHRoYXQgZmFpbGVkIHZhbGlkYXRpb24gKi9cclxuICBmaWVsZDogc3RyaW5nO1xyXG4gIC8qKiBWYWxpZGF0aW9uIHJ1bGUgdGhhdCBmYWlsZWQgKi9cclxuICBydWxlOiBzdHJpbmc7XHJcbiAgLyoqIEVycm9yIG1lc3NhZ2UgKi9cclxuICBtZXNzYWdlOiBzdHJpbmc7XHJcbiAgLyoqIEV4cGVjdGVkIHZhbHVlIG9yIGZvcm1hdCAqL1xyXG4gIGV4cGVjdGVkPzogc3RyaW5nO1xyXG4gIC8qKiBBY3R1YWwgdmFsdWUgcmVjZWl2ZWQgKi9cclxuICBhY3R1YWw/OiB1bmtub3duO1xyXG59XHJcblxyXG4vKipcclxuICogRXJyb3IgZmFjdG9yeSBvcHRpb25zXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIEVycm9yT3B0aW9ucyB7XHJcbiAgY29kZT86IHN0cmluZztcclxuICBzZXZlcml0eT86IEVycm9yU2V2ZXJpdHk7XHJcbiAgY2F0ZWdvcnk/OiBFcnJvckNhdGVnb3J5O1xyXG4gIGNvbnRleHQ/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcclxuICByZWNvdmVyeUFjdGlvbj86IHN0cmluZztcclxuICByZWNvdmVyYWJsZT86IGJvb2xlYW47XHJcbiAgb3JpZ2luYWxFcnJvcj86IEVycm9yO1xyXG59XHJcblxyXG4vKipcclxuICogQ3JlYXRlIGEgc3RhbmRhcmRpemVkIFBFQ0IgZXJyb3JcclxuICogQHBhcmFtIG1lc3NhZ2UgLSBFcnJvciBtZXNzYWdlXHJcbiAqIEBwYXJhbSBvcHRpb25zIC0gQWRkaXRpb25hbCBlcnJvciBvcHRpb25zXHJcbiAqIEByZXR1cm5zIEEgc3RhbmRhcmRpemVkIFBlY2JFcnJvciBvYmplY3RcclxuICpcclxuICogQGV4YW1wbGVcclxuICogY29uc3QgZXJyb3IgPSBjcmVhdGVFcnJvcignSW52YWxpZCBpbnB1dCcsIHtcclxuICogICBjb2RlOiAnVkFMSURBVElPTl8wMDEnLFxyXG4gKiAgIGNhdGVnb3J5OiAndmFsaWRhdGlvbicsXHJcbiAqICAgc2V2ZXJpdHk6ICd3YXJuaW5nJyxcclxuICogICByZWNvdmVyYWJsZTogdHJ1ZVxyXG4gKiB9KTtcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVFcnJvcihtZXNzYWdlOiBzdHJpbmcsIG9wdGlvbnM6IEVycm9yT3B0aW9ucyA9IHt9KTogUGVjYkVycm9yIHtcclxuICByZXR1cm4ge1xyXG4gICAgY29kZTogb3B0aW9ucy5jb2RlID8/ICdQRUNCX0VSUk9SJyxcclxuICAgIG1lc3NhZ2UsXHJcbiAgICBzZXZlcml0eTogb3B0aW9ucy5zZXZlcml0eSA/PyAnZXJyb3InLFxyXG4gICAgY2F0ZWdvcnk6IG9wdGlvbnMuY2F0ZWdvcnkgPz8gJ3Vua25vd24nLFxyXG4gICAgb3JpZ2luYWxFcnJvcjogb3B0aW9ucy5vcmlnaW5hbEVycm9yLFxyXG4gICAgY29udGV4dDogb3B0aW9ucy5jb250ZXh0LFxyXG4gICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLFxyXG4gICAgcmVjb3ZlcnlBY3Rpb246IG9wdGlvbnMucmVjb3ZlcnlBY3Rpb24sXHJcbiAgICByZWNvdmVyYWJsZTogb3B0aW9ucy5yZWNvdmVyYWJsZSA/PyBmYWxzZVxyXG4gIH07XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDcmVhdGUgYSB2YWxpZGF0aW9uIGVycm9yXHJcbiAqIEBwYXJhbSBmaWVsZCAtIEZpZWxkIG5hbWUgdGhhdCBmYWlsZWQgdmFsaWRhdGlvblxyXG4gKiBAcGFyYW0gcnVsZSAtIFZhbGlkYXRpb24gcnVsZSB0aGF0IGZhaWxlZFxyXG4gKiBAcGFyYW0gbWVzc2FnZSAtIEVycm9yIG1lc3NhZ2VcclxuICogQHJldHVybnMgQSBWYWxpZGF0aW9uRXJyb3Igb2JqZWN0XHJcbiAqXHJcbiAqIEBleGFtcGxlXHJcbiAqIGNvbnN0IGVycm9yID0gY3JlYXRlVmFsaWRhdGlvbkVycm9yKCdlbWFpbCcsICdmb3JtYXQnLCAnSW52YWxpZCBlbWFpbCBmb3JtYXQnKTtcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVWYWxpZGF0aW9uRXJyb3IoXHJcbiAgZmllbGQ6IHN0cmluZyxcclxuICBydWxlOiBzdHJpbmcsXHJcbiAgbWVzc2FnZTogc3RyaW5nLFxyXG4gIGRldGFpbHM/OiB7IGV4cGVjdGVkPzogc3RyaW5nOyBhY3R1YWw/OiB1bmtub3duIH1cclxuKTogVmFsaWRhdGlvbkVycm9yIHtcclxuICByZXR1cm4ge1xyXG4gICAgZmllbGQsXHJcbiAgICBydWxlLFxyXG4gICAgbWVzc2FnZSxcclxuICAgIGV4cGVjdGVkOiBkZXRhaWxzPy5leHBlY3RlZCxcclxuICAgIGFjdHVhbDogZGV0YWlscz8uYWN0dWFsXHJcbiAgfTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFdyYXAgYW4gdW5rbm93biBlcnJvciBpbiBhIFBlY2JFcnJvclxyXG4gKiBAcGFyYW0gZXJyb3IgLSBUaGUgZXJyb3IgdG8gd3JhcFxyXG4gKiBAcGFyYW0gb3B0aW9ucyAtIEFkZGl0aW9uYWwgb3B0aW9uc1xyXG4gKiBAcmV0dXJucyBBIHN0YW5kYXJkaXplZCBQZWNiRXJyb3JcclxuICpcclxuICogQGV4YW1wbGVcclxuICogdHJ5IHtcclxuICogICBhd2FpdCByaXNreU9wZXJhdGlvbigpO1xyXG4gKiB9IGNhdGNoIChlKSB7XHJcbiAqICAgY29uc3QgZXJyb3IgPSB3cmFwRXJyb3IoZSwgeyBjYXRlZ29yeTogJ25ldHdvcmsnIH0pO1xyXG4gKiAgIGhhbmRsZUVycm9yKGVycm9yKTtcclxuICogfVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHdyYXBFcnJvcihlcnJvcjogdW5rbm93biwgb3B0aW9uczogRXJyb3JPcHRpb25zID0ge30pOiBQZWNiRXJyb3Ige1xyXG4gIGlmIChpc1BlY2JFcnJvcihlcnJvcikpIHtcclxuICAgIHJldHVybiBlcnJvcjtcclxuICB9XHJcblxyXG4gIGxldCBtZXNzYWdlID0gJ0FuIHVua25vd24gZXJyb3Igb2NjdXJyZWQnO1xyXG4gIGxldCBvcmlnaW5hbEVycm9yOiBFcnJvciB8IHVuZGVmaW5lZDtcclxuXHJcbiAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcclxuICAgIG1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlO1xyXG4gICAgb3JpZ2luYWxFcnJvciA9IGVycm9yO1xyXG4gIH0gZWxzZSBpZiAodHlwZW9mIGVycm9yID09PSAnc3RyaW5nJykge1xyXG4gICAgbWVzc2FnZSA9IGVycm9yO1xyXG4gIH0gZWxzZSBpZiAoZXJyb3IgJiYgdHlwZW9mIGVycm9yID09PSAnb2JqZWN0JyAmJiAnbWVzc2FnZScgaW4gZXJyb3IpIHtcclxuICAgIG1lc3NhZ2UgPSBTdHJpbmcoKGVycm9yIGFzIHsgbWVzc2FnZTogdW5rbm93biB9KS5tZXNzYWdlKTtcclxuICB9XHJcblxyXG4gIHJldHVybiBjcmVhdGVFcnJvcihtZXNzYWdlLCB7XHJcbiAgICAuLi5vcHRpb25zLFxyXG4gICAgb3JpZ2luYWxFcnJvclxyXG4gIH0pO1xyXG59XHJcblxyXG4vKipcclxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhbiBvYmplY3QgaXMgYSBQZWNiRXJyb3JcclxuICogQHBhcmFtIGVycm9yIC0gVGhlIG9iamVjdCB0byBjaGVja1xyXG4gKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBvYmplY3QgaXMgYSBQZWNiRXJyb3JcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBpc1BlY2JFcnJvcihlcnJvcjogdW5rbm93bik6IGVycm9yIGlzIFBlY2JFcnJvciB7XHJcbiAgcmV0dXJuIChcclxuICAgIGVycm9yICE9PSBudWxsICYmXHJcbiAgICB0eXBlb2YgZXJyb3IgPT09ICdvYmplY3QnICYmXHJcbiAgICAnY29kZScgaW4gZXJyb3IgJiZcclxuICAgICdtZXNzYWdlJyBpbiBlcnJvciAmJlxyXG4gICAgJ3NldmVyaXR5JyBpbiBlcnJvciAmJlxyXG4gICAgJ2NhdGVnb3J5JyBpbiBlcnJvciAmJlxyXG4gICAgJ3RpbWVzdGFtcCcgaW4gZXJyb3JcclxuICApO1xyXG59XHJcblxyXG4vKipcclxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhbiBlcnJvciBpcyByZWNvdmVyYWJsZVxyXG4gKiBAcGFyYW0gZXJyb3IgLSBUaGUgZXJyb3IgdG8gY2hlY2tcclxuICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgZXJyb3IgaXMgcmVjb3ZlcmFibGVcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBpc1JlY292ZXJhYmxlRXJyb3IoZXJyb3I6IFBlY2JFcnJvcik6IGJvb2xlYW4ge1xyXG4gIHJldHVybiBlcnJvci5yZWNvdmVyYWJsZTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEZvcm1hdCBhbiBlcnJvciBmb3IgZGlzcGxheSB0byB1c2Vyc1xyXG4gKiBAcGFyYW0gZXJyb3IgLSBUaGUgZXJyb3IgdG8gZm9ybWF0XHJcbiAqIEBwYXJhbSBpbmNsdWRlQ29kZSAtIFdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgZXJyb3IgY29kZVxyXG4gKiBAcmV0dXJucyBGb3JtYXR0ZWQgZXJyb3IgbWVzc2FnZVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdEVycm9yTWVzc2FnZShlcnJvcjogUGVjYkVycm9yLCBpbmNsdWRlQ29kZSA9IGZhbHNlKTogc3RyaW5nIHtcclxuICBpZiAoaW5jbHVkZUNvZGUpIHtcclxuICAgIHJldHVybiBgWyR7ZXJyb3IuY29kZX1dICR7ZXJyb3IubWVzc2FnZX1gO1xyXG4gIH1cclxuICByZXR1cm4gZXJyb3IubWVzc2FnZTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEZvcm1hdCBhbiBlcnJvciBmb3IgbG9nZ2luZ1xyXG4gKiBAcGFyYW0gZXJyb3IgLSBUaGUgZXJyb3IgdG8gZm9ybWF0XHJcbiAqIEByZXR1cm5zIEZvcm1hdHRlZCBlcnJvciBzdHJpbmcgZm9yIGxvZ2dpbmdcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBmb3JtYXRFcnJvckZvckxvZyhlcnJvcjogUGVjYkVycm9yKTogc3RyaW5nIHtcclxuICBjb25zdCBwYXJ0cyA9IFtcclxuICAgIGBbJHtlcnJvci50aW1lc3RhbXAudG9JU09TdHJpbmcoKX1dYCxcclxuICAgIGBbJHtlcnJvci5zZXZlcml0eS50b1VwcGVyQ2FzZSgpfV1gLFxyXG4gICAgYFske2Vycm9yLmNvZGV9XWAsXHJcbiAgICBlcnJvci5tZXNzYWdlXHJcbiAgXTtcclxuXHJcbiAgaWYgKGVycm9yLmNvbnRleHQpIHtcclxuICAgIHBhcnRzLnB1c2goYENvbnRleHQ6ICR7SlNPTi5zdHJpbmdpZnkoZXJyb3IuY29udGV4dCl9YCk7XHJcbiAgfVxyXG5cclxuICBpZiAoZXJyb3Iub3JpZ2luYWxFcnJvcj8uc3RhY2spIHtcclxuICAgIHBhcnRzLnB1c2goYFN0YWNrOiAke2Vycm9yLm9yaWdpbmFsRXJyb3Iuc3RhY2t9YCk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gcGFydHMuam9pbignICcpO1xyXG59XHJcblxyXG4vKipcclxuICogQ3JlYXRlIGEgbmV0d29yayBlcnJvclxyXG4gKiBAcGFyYW0gbWVzc2FnZSAtIEVycm9yIG1lc3NhZ2VcclxuICogQHBhcmFtIHN0YXR1c0NvZGUgLSBIVFRQIHN0YXR1cyBjb2RlIGlmIGFwcGxpY2FibGVcclxuICogQHBhcmFtIG9yaWdpbmFsRXJyb3IgLSBPcmlnaW5hbCBlcnJvclxyXG4gKiBAcmV0dXJucyBBIG5ldHdvcmsgY2F0ZWdvcnkgUGVjYkVycm9yXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTmV0d29ya0Vycm9yKFxyXG4gIG1lc3NhZ2U6IHN0cmluZyxcclxuICBzdGF0dXNDb2RlPzogbnVtYmVyLFxyXG4gIG9yaWdpbmFsRXJyb3I/OiBFcnJvclxyXG4pOiBQZWNiRXJyb3Ige1xyXG4gIHJldHVybiBjcmVhdGVFcnJvcihtZXNzYWdlLCB7XHJcbiAgICBjb2RlOiBzdGF0dXNDb2RlID8gYE5FVFdPUktfJHtzdGF0dXNDb2RlfWAgOiAnTkVUV09SS19FUlJPUicsXHJcbiAgICBjYXRlZ29yeTogJ25ldHdvcmsnLFxyXG4gICAgc2V2ZXJpdHk6ICdlcnJvcicsXHJcbiAgICBjb250ZXh0OiBzdGF0dXNDb2RlID8geyBzdGF0dXNDb2RlIH0gOiB1bmRlZmluZWQsXHJcbiAgICByZWNvdmVyYWJsZTogdHJ1ZSxcclxuICAgIHJlY292ZXJ5QWN0aW9uOiAnUGxlYXNlIGNoZWNrIHlvdXIgY29ubmVjdGlvbiBhbmQgdHJ5IGFnYWluJyxcclxuICAgIG9yaWdpbmFsRXJyb3JcclxuICB9KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENyZWF0ZSBhbiBhdXRoZW50aWNhdGlvbiBlcnJvclxyXG4gKiBAcGFyYW0gbWVzc2FnZSAtIEVycm9yIG1lc3NhZ2VcclxuICogQHBhcmFtIG9yaWdpbmFsRXJyb3IgLSBPcmlnaW5hbCBlcnJvclxyXG4gKiBAcmV0dXJucyBBbiBhdXRoZW50aWNhdGlvbiBjYXRlZ29yeSBQZWNiRXJyb3JcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVBdXRoRXJyb3IobWVzc2FnZTogc3RyaW5nLCBvcmlnaW5hbEVycm9yPzogRXJyb3IpOiBQZWNiRXJyb3Ige1xyXG4gIHJldHVybiBjcmVhdGVFcnJvcihtZXNzYWdlLCB7XHJcbiAgICBjb2RlOiAnQVVUSF9FUlJPUicsXHJcbiAgICBjYXRlZ29yeTogJ2F1dGhlbnRpY2F0aW9uJyxcclxuICAgIHNldmVyaXR5OiAnZXJyb3InLFxyXG4gICAgcmVjb3ZlcmFibGU6IHRydWUsXHJcbiAgICByZWNvdmVyeUFjdGlvbjogJ1BsZWFzZSBzaWduIGluIGFnYWluJyxcclxuICAgIG9yaWdpbmFsRXJyb3JcclxuICB9KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENyZWF0ZSBhbiBhdXRob3JpemF0aW9uIGVycm9yXHJcbiAqIEBwYXJhbSBtZXNzYWdlIC0gRXJyb3IgbWVzc2FnZVxyXG4gKiBAcGFyYW0gcmVzb3VyY2UgLSBUaGUgcmVzb3VyY2UgdGhhdCBhY2Nlc3Mgd2FzIGRlbmllZCB0b1xyXG4gKiBAcmV0dXJucyBBbiBhdXRob3JpemF0aW9uIGNhdGVnb3J5IFBlY2JFcnJvclxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUF1dGhvcml6YXRpb25FcnJvcihtZXNzYWdlOiBzdHJpbmcsIHJlc291cmNlPzogc3RyaW5nKTogUGVjYkVycm9yIHtcclxuICByZXR1cm4gY3JlYXRlRXJyb3IobWVzc2FnZSwge1xyXG4gICAgY29kZTogJ0FVVEhaX0VSUk9SJyxcclxuICAgIGNhdGVnb3J5OiAnYXV0aG9yaXphdGlvbicsXHJcbiAgICBzZXZlcml0eTogJ3dhcm5pbmcnLFxyXG4gICAgY29udGV4dDogcmVzb3VyY2UgPyB7IHJlc291cmNlIH0gOiB1bmRlZmluZWQsXHJcbiAgICByZWNvdmVyYWJsZTogZmFsc2UsXHJcbiAgICByZWNvdmVyeUFjdGlvbjogJ0NvbnRhY3QgYW4gYWRtaW5pc3RyYXRvciBmb3IgYWNjZXNzJ1xyXG4gIH0pO1xyXG59XHJcblxyXG4vKipcclxuICogQ3JlYXRlIGEgY29uZmlndXJhdGlvbiBlcnJvclxyXG4gKiBAcGFyYW0gbWVzc2FnZSAtIEVycm9yIG1lc3NhZ2VcclxuICogQHBhcmFtIGNvbmZpZ0tleSAtIFRoZSBjb25maWd1cmF0aW9uIGtleSB0aGF0IGlzIGludmFsaWRcclxuICogQHJldHVybnMgQSBjb25maWd1cmF0aW9uIGNhdGVnb3J5IFBlY2JFcnJvclxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNvbmZpZ0Vycm9yKG1lc3NhZ2U6IHN0cmluZywgY29uZmlnS2V5Pzogc3RyaW5nKTogUGVjYkVycm9yIHtcclxuICByZXR1cm4gY3JlYXRlRXJyb3IobWVzc2FnZSwge1xyXG4gICAgY29kZTogJ0NPTkZJR19FUlJPUicsXHJcbiAgICBjYXRlZ29yeTogJ2NvbmZpZ3VyYXRpb24nLFxyXG4gICAgc2V2ZXJpdHk6ICdjcml0aWNhbCcsXHJcbiAgICBjb250ZXh0OiBjb25maWdLZXkgPyB7IGNvbmZpZ0tleSB9IDogdW5kZWZpbmVkLFxyXG4gICAgcmVjb3ZlcmFibGU6IGZhbHNlLFxyXG4gICAgcmVjb3ZlcnlBY3Rpb246ICdDaGVjayB5b3VyIGNvbmZpZ3VyYXRpb24gc2V0dGluZ3MnXHJcbiAgfSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBFcnJvciBoYW5kbGVyIHR5cGVcclxuICovXHJcbmV4cG9ydCB0eXBlIEVycm9ySGFuZGxlciA9IChlcnJvcjogUGVjYkVycm9yKSA9PiB2b2lkO1xyXG5cclxuLyoqXHJcbiAqIEdsb2JhbCBlcnJvciBoYW5kbGVyIHJlZ2lzdHJ5XHJcbiAqL1xyXG5jb25zdCBlcnJvckhhbmRsZXJzOiBNYXA8RXJyb3JDYXRlZ29yeSwgRXJyb3JIYW5kbGVyW10+ID0gbmV3IE1hcCgpO1xyXG5cclxuLyoqXHJcbiAqIFJlZ2lzdGVyIGFuIGVycm9yIGhhbmRsZXIgZm9yIGEgY2F0ZWdvcnlcclxuICogQHBhcmFtIGNhdGVnb3J5IC0gVGhlIGVycm9yIGNhdGVnb3J5IHRvIGhhbmRsZVxyXG4gKiBAcGFyYW0gaGFuZGxlciAtIFRoZSBoYW5kbGVyIGZ1bmN0aW9uXHJcbiAqIEByZXR1cm5zIENsZWFudXAgZnVuY3Rpb24gdG8gdW5yZWdpc3RlclxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyRXJyb3JIYW5kbGVyKGNhdGVnb3J5OiBFcnJvckNhdGVnb3J5LCBoYW5kbGVyOiBFcnJvckhhbmRsZXIpOiAoKSA9PiB2b2lkIHtcclxuICBjb25zdCBoYW5kbGVycyA9IGVycm9ySGFuZGxlcnMuZ2V0KGNhdGVnb3J5KSA/PyBbXTtcclxuICBoYW5kbGVycy5wdXNoKGhhbmRsZXIpO1xyXG4gIGVycm9ySGFuZGxlcnMuc2V0KGNhdGVnb3J5LCBoYW5kbGVycyk7XHJcblxyXG4gIHJldHVybiAoKSA9PiB7XHJcbiAgICBjb25zdCBjdXJyZW50SGFuZGxlcnMgPSBlcnJvckhhbmRsZXJzLmdldChjYXRlZ29yeSk7XHJcbiAgICBpZiAoY3VycmVudEhhbmRsZXJzKSB7XHJcbiAgICAgIGNvbnN0IGluZGV4ID0gY3VycmVudEhhbmRsZXJzLmluZGV4T2YoaGFuZGxlcik7XHJcbiAgICAgIGlmIChpbmRleCA+IC0xKSB7XHJcbiAgICAgICAgY3VycmVudEhhbmRsZXJzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9O1xyXG59XHJcblxyXG4vKipcclxuICogSGFuZGxlIGFuIGVycm9yIGJ5IGludm9raW5nIHJlZ2lzdGVyZWQgaGFuZGxlcnNcclxuICogQHBhcmFtIGVycm9yIC0gVGhlIGVycm9yIHRvIGhhbmRsZVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZUVycm9yKGVycm9yOiBQZWNiRXJyb3IpOiB2b2lkIHtcclxuICBjb25zdCBoYW5kbGVycyA9IGVycm9ySGFuZGxlcnMuZ2V0KGVycm9yLmNhdGVnb3J5KSA/PyBbXTtcclxuICBjb25zdCBnbG9iYWxIYW5kbGVycyA9IGVycm9ySGFuZGxlcnMuZ2V0KCd1bmtub3duJykgPz8gW107XHJcblxyXG4gIFsuLi5oYW5kbGVycywgLi4uZ2xvYmFsSGFuZGxlcnNdLmZvckVhY2goaGFuZGxlciA9PiB7XHJcbiAgICB0cnkge1xyXG4gICAgICBoYW5kbGVyKGVycm9yKTtcclxuICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgaW4gZXJyb3IgaGFuZGxlcjonLCBlKTtcclxuICAgIH1cclxuICB9KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFRyeSB0byBleGVjdXRlIGFuIG9wZXJhdGlvbiBhbmQgcmV0dXJuIGEgcmVzdWx0IG9yIGVycm9yXHJcbiAqIEBwYXJhbSBvcGVyYXRpb24gLSBUaGUgb3BlcmF0aW9uIHRvIGV4ZWN1dGVcclxuICogQHBhcmFtIGVycm9yT3B0aW9ucyAtIE9wdGlvbnMgZm9yIGVycm9yIHdyYXBwaW5nXHJcbiAqIEByZXR1cm5zIEEgdHVwbGUgb2YgW3Jlc3VsdCwgbnVsbF0gb3IgW251bGwsIGVycm9yXVxyXG4gKi9cclxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRyeUFzeW5jPFQ+KFxyXG4gIG9wZXJhdGlvbjogKCkgPT4gUHJvbWlzZTxUPixcclxuICBlcnJvck9wdGlvbnM/OiBFcnJvck9wdGlvbnNcclxuKTogUHJvbWlzZTxbVCwgbnVsbF0gfCBbbnVsbCwgUGVjYkVycm9yXT4ge1xyXG4gIHRyeSB7XHJcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBvcGVyYXRpb24oKTtcclxuICAgIHJldHVybiBbcmVzdWx0LCBudWxsXTtcclxuICB9IGNhdGNoIChlKSB7XHJcbiAgICByZXR1cm4gW251bGwsIHdyYXBFcnJvcihlLCBlcnJvck9wdGlvbnMpXTtcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBTeW5jaHJvbm91cyB2ZXJzaW9uIG9mIHRyeUFzeW5jXHJcbiAqIEBwYXJhbSBvcGVyYXRpb24gLSBUaGUgb3BlcmF0aW9uIHRvIGV4ZWN1dGVcclxuICogQHBhcmFtIGVycm9yT3B0aW9ucyAtIE9wdGlvbnMgZm9yIGVycm9yIHdyYXBwaW5nXHJcbiAqIEByZXR1cm5zIEEgdHVwbGUgb2YgW3Jlc3VsdCwgbnVsbF0gb3IgW251bGwsIGVycm9yXVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHRyeVN5bmM8VD4oXHJcbiAgb3BlcmF0aW9uOiAoKSA9PiBULFxyXG4gIGVycm9yT3B0aW9ucz86IEVycm9yT3B0aW9uc1xyXG4pOiBbVCwgbnVsbF0gfCBbbnVsbCwgUGVjYkVycm9yXSB7XHJcbiAgdHJ5IHtcclxuICAgIGNvbnN0IHJlc3VsdCA9IG9wZXJhdGlvbigpO1xyXG4gICAgcmV0dXJuIFtyZXN1bHQsIG51bGxdO1xyXG4gIH0gY2F0Y2ggKGUpIHtcclxuICAgIHJldHVybiBbbnVsbCwgd3JhcEVycm9yKGUsIGVycm9yT3B0aW9ucyldO1xyXG4gIH1cclxufVxyXG4iXX0=
|