@aquera/ngx-smart-table 0.0.17-alpha → 0.0.18-alpha
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/{fesm2020 → fesm2022}/aquera-ngx-smart-table.mjs +1579 -2101
- package/fesm2022/aquera-ngx-smart-table.mjs.map +1 -0
- package/package.json +8 -16
- package/types/aquera-ngx-smart-table.d.ts +5909 -0
- package/aquera-ngx-smart-table.d.ts +0 -5
- package/esm2020/aquera-ngx-smart-table.mjs +0 -5
- package/esm2020/lib/builder/components/builder-preview/builder-preview.component.mjs +0 -63
- package/esm2020/lib/builder/components/builder-toolbar/builder-toolbar.component.mjs +0 -115
- package/esm2020/lib/builder/components/column-editor/column-editor.component.mjs +0 -206
- package/esm2020/lib/builder/components/column-list/column-list.component.mjs +0 -125
- package/esm2020/lib/builder/components/definition-builder/definition-builder.component.mjs +0 -105
- package/esm2020/lib/builder/components/table-config-editor/table-config-editor.component.mjs +0 -132
- package/esm2020/lib/builder/definition-builder.module.mjs +0 -70
- package/esm2020/lib/builder/models/builder-state.interface.mjs +0 -5
- package/esm2020/lib/builder/services/definition-builder.service.mjs +0 -251
- package/esm2020/lib/builder/services/definition-export.service.mjs +0 -167
- package/esm2020/lib/builder/services/definition-import.service.mjs +0 -193
- package/esm2020/lib/builder/services/sample-data-generator.service.mjs +0 -126
- package/esm2020/lib/builder/utils/config-validator.util.mjs +0 -165
- package/esm2020/lib/builder/utils/typescript-generator.util.mjs +0 -206
- package/esm2020/lib/editors/index.mjs +0 -9
- package/esm2020/lib/editors/nile-autocomplete-editor.mjs +0 -228
- package/esm2020/lib/editors/nile-calendar-editor.mjs +0 -211
- package/esm2020/lib/editors/nile-date-picker-editor.mjs +0 -188
- package/esm2020/lib/editors/nile-input-editor.mjs +0 -235
- package/esm2020/lib/editors/nile-select-editor.mjs +0 -498
- package/esm2020/lib/factories/column-config.factory.mjs +0 -231
- package/esm2020/lib/models/autosave-config.interface.mjs +0 -8
- package/esm2020/lib/models/base-column-config.class.mjs +0 -253
- package/esm2020/lib/models/cell-strategies.interface.mjs +0 -6
- package/esm2020/lib/models/cell-types.mjs +0 -147
- package/esm2020/lib/models/column-action.interface.mjs +0 -6
- package/esm2020/lib/models/column-config.interface.mjs +0 -43
- package/esm2020/lib/models/column-config.utils.mjs +0 -101
- package/esm2020/lib/models/row-action.interface.mjs +0 -5
- package/esm2020/lib/models/row-validator.interface.mjs +0 -2
- package/esm2020/lib/models/schema-validation.interface.mjs +0 -2
- package/esm2020/lib/models/sheet-action.interface.mjs +0 -5
- package/esm2020/lib/models/sheet-config.interface.mjs +0 -5
- package/esm2020/lib/models/table-config.interface.mjs +0 -107
- package/esm2020/lib/models/table-validator.interface.mjs +0 -2
- package/esm2020/lib/models/workbook-action.interface.mjs +0 -5
- package/esm2020/lib/models/workbook-config.interface.mjs +0 -5
- package/esm2020/lib/renderer/components/st-add-column-button/st-add-column-button.component.mjs +0 -24
- package/esm2020/lib/renderer/components/st-cell/st-cell.component.mjs +0 -397
- package/esm2020/lib/renderer/components/st-column-editor-modal/st-column-editor-modal.component.mjs +0 -103
- package/esm2020/lib/renderer/components/st-column-filter/st-column-filter.component.mjs +0 -383
- package/esm2020/lib/renderer/components/st-column-menu/st-column-menu.component.mjs +0 -232
- package/esm2020/lib/renderer/components/st-column-visibility/st-column-visibility.component.mjs +0 -97
- package/esm2020/lib/renderer/components/st-header/st-header.component.mjs +0 -157
- package/esm2020/lib/renderer/components/st-pagination/st-pagination.component.mjs +0 -87
- package/esm2020/lib/renderer/components/st-row-actions-dropdown/st-row-actions-dropdown.component.mjs +0 -167
- package/esm2020/lib/renderer/components/st-sheet/st-sheet.component.mjs +0 -165
- package/esm2020/lib/renderer/components/st-sheet-actions/st-sheet-actions.component.mjs +0 -112
- package/esm2020/lib/renderer/components/st-table/st-table.component.mjs +0 -1453
- package/esm2020/lib/renderer/components/st-table-actions/st-table-actions.component.mjs +0 -169
- package/esm2020/lib/renderer/components/st-workbook/st-workbook.component.mjs +0 -581
- package/esm2020/lib/renderer/directives/click-outside.directive.mjs +0 -28
- package/esm2020/lib/renderer/directives/st-column-resize.directive.mjs +0 -108
- package/esm2020/lib/renderer/directives/st-keyboard-navigation.directive.mjs +0 -83
- package/esm2020/lib/renderer/models/cell-state.interface.mjs +0 -66
- package/esm2020/lib/renderer/models/cell.class.mjs +0 -389
- package/esm2020/lib/renderer/models/row-validation-state.interface.mjs +0 -7
- package/esm2020/lib/renderer/models/sheet-state.class.mjs +0 -90
- package/esm2020/lib/renderer/models/sheet-state.interface.mjs +0 -5
- package/esm2020/lib/renderer/models/table-state.class.mjs +0 -871
- package/esm2020/lib/renderer/models/table-state.interface.mjs +0 -5
- package/esm2020/lib/renderer/models/table-types.mjs +0 -29
- package/esm2020/lib/renderer/models/table-validation-state.interface.mjs +0 -7
- package/esm2020/lib/renderer/models/workbook-state.class.mjs +0 -174
- package/esm2020/lib/renderer/models/workbook-state.interface.mjs +0 -5
- package/esm2020/lib/renderer/models/z-index.enum.mjs +0 -55
- package/esm2020/lib/schemas/table-config.schema.mjs +0 -472
- package/esm2020/lib/services/autosave.service.mjs +0 -92
- package/esm2020/lib/services/custom-validation-rules.util.mjs +0 -124
- package/esm2020/lib/services/json-schema-validator.service.mjs +0 -216
- package/esm2020/lib/services/row-validation.service.mjs +0 -42
- package/esm2020/lib/services/validation-logger.service.mjs +0 -177
- package/esm2020/lib/services/virtual-scroll.service.mjs +0 -52
- package/esm2020/lib/shared/shared-table-components.module.mjs +0 -35
- package/esm2020/lib/smart-table.module.mjs +0 -124
- package/esm2020/lib/strategies/default-editors.mjs +0 -433
- package/esm2020/lib/strategies/default-formatters.mjs +0 -238
- package/esm2020/lib/strategies/default-validators.mjs +0 -327
- package/esm2020/public-api.mjs +0 -146
- package/fesm2015/aquera-ngx-smart-table.mjs +0 -12347
- package/fesm2015/aquera-ngx-smart-table.mjs.map +0 -1
- package/fesm2020/aquera-ngx-smart-table.mjs.map +0 -1
- package/lib/builder/components/builder-preview/builder-preview.component.d.ts +0 -31
- package/lib/builder/components/builder-toolbar/builder-toolbar.component.d.ts +0 -53
- package/lib/builder/components/column-editor/column-editor.component.d.ts +0 -69
- package/lib/builder/components/column-list/column-list.component.d.ts +0 -65
- package/lib/builder/components/definition-builder/definition-builder.component.d.ts +0 -58
- package/lib/builder/components/table-config-editor/table-config-editor.component.d.ts +0 -32
- package/lib/builder/definition-builder.module.d.ts +0 -15
- package/lib/builder/models/builder-state.interface.d.ts +0 -93
- package/lib/builder/services/definition-builder.service.d.ts +0 -80
- package/lib/builder/services/definition-export.service.d.ts +0 -59
- package/lib/builder/services/definition-import.service.d.ts +0 -31
- package/lib/builder/services/sample-data-generator.service.d.ts +0 -41
- package/lib/builder/utils/config-validator.util.d.ts +0 -32
- package/lib/builder/utils/typescript-generator.util.d.ts +0 -29
- package/lib/editors/index.d.ts +0 -8
- package/lib/editors/nile-autocomplete-editor.d.ts +0 -102
- package/lib/editors/nile-calendar-editor.d.ts +0 -88
- package/lib/editors/nile-date-picker-editor.d.ts +0 -97
- package/lib/editors/nile-input-editor.d.ts +0 -67
- package/lib/editors/nile-select-editor.d.ts +0 -113
- package/lib/factories/column-config.factory.d.ts +0 -73
- package/lib/models/autosave-config.interface.d.ts +0 -23
- package/lib/models/base-column-config.class.d.ts +0 -115
- package/lib/models/cell-strategies.interface.d.ts +0 -188
- package/lib/models/cell-types.d.ts +0 -337
- package/lib/models/column-action.interface.d.ts +0 -86
- package/lib/models/column-config.interface.d.ts +0 -272
- package/lib/models/column-config.utils.d.ts +0 -37
- package/lib/models/row-action.interface.d.ts +0 -86
- package/lib/models/row-validator.interface.d.ts +0 -37
- package/lib/models/schema-validation.interface.d.ts +0 -42
- package/lib/models/sheet-action.interface.d.ts +0 -59
- package/lib/models/sheet-config.interface.d.ts +0 -41
- package/lib/models/table-config.interface.d.ts +0 -251
- package/lib/models/table-validator.interface.d.ts +0 -40
- package/lib/models/workbook-action.interface.d.ts +0 -95
- package/lib/models/workbook-config.interface.d.ts +0 -107
- package/lib/renderer/components/st-add-column-button/st-add-column-button.component.d.ts +0 -9
- package/lib/renderer/components/st-cell/st-cell.component.d.ts +0 -69
- package/lib/renderer/components/st-column-editor-modal/st-column-editor-modal.component.d.ts +0 -39
- package/lib/renderer/components/st-column-filter/st-column-filter.component.d.ts +0 -139
- package/lib/renderer/components/st-column-menu/st-column-menu.component.d.ts +0 -81
- package/lib/renderer/components/st-column-visibility/st-column-visibility.component.d.ts +0 -44
- package/lib/renderer/components/st-header/st-header.component.d.ts +0 -93
- package/lib/renderer/components/st-pagination/st-pagination.component.d.ts +0 -42
- package/lib/renderer/components/st-row-actions-dropdown/st-row-actions-dropdown.component.d.ts +0 -67
- package/lib/renderer/components/st-sheet/st-sheet.component.d.ts +0 -98
- package/lib/renderer/components/st-sheet-actions/st-sheet-actions.component.d.ts +0 -58
- package/lib/renderer/components/st-table/st-table.component.d.ts +0 -380
- package/lib/renderer/components/st-table-actions/st-table-actions.component.d.ts +0 -77
- package/lib/renderer/components/st-workbook/st-workbook.component.d.ts +0 -275
- package/lib/renderer/directives/click-outside.directive.d.ts +0 -10
- package/lib/renderer/directives/st-column-resize.directive.d.ts +0 -44
- package/lib/renderer/directives/st-keyboard-navigation.directive.d.ts +0 -19
- package/lib/renderer/models/cell-state.interface.d.ts +0 -118
- package/lib/renderer/models/cell.class.d.ts +0 -174
- package/lib/renderer/models/row-validation-state.interface.d.ts +0 -27
- package/lib/renderer/models/sheet-state.class.d.ts +0 -67
- package/lib/renderer/models/sheet-state.interface.d.ts +0 -55
- package/lib/renderer/models/table-state.class.d.ts +0 -320
- package/lib/renderer/models/table-state.interface.d.ts +0 -18
- package/lib/renderer/models/table-types.d.ts +0 -228
- package/lib/renderer/models/table-validation-state.interface.d.ts +0 -34
- package/lib/renderer/models/workbook-state.class.d.ts +0 -117
- package/lib/renderer/models/workbook-state.interface.d.ts +0 -71
- package/lib/renderer/models/z-index.enum.d.ts +0 -44
- package/lib/schemas/table-config.schema.d.ts +0 -455
- package/lib/services/autosave.service.d.ts +0 -73
- package/lib/services/custom-validation-rules.util.d.ts +0 -12
- package/lib/services/json-schema-validator.service.d.ts +0 -49
- package/lib/services/row-validation.service.d.ts +0 -17
- package/lib/services/validation-logger.service.d.ts +0 -87
- package/lib/services/virtual-scroll.service.d.ts +0 -44
- package/lib/shared/shared-table-components.module.d.ts +0 -9
- package/lib/smart-table.module.d.ts +0 -26
- package/lib/strategies/default-editors.d.ts +0 -109
- package/lib/strategies/default-formatters.d.ts +0 -116
- package/lib/strategies/default-validators.d.ts +0 -113
- package/public-api.d.ts +0 -70
- package/src/lib/builder/README.md +0 -30
- package/src/lib/editors/README.md +0 -303
- package/src/lib/renderer/components/st-column-filter/README.md +0 -286
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom validation rules utility
|
|
3
|
-
* Implements business logic validations that can't be expressed in JSON Schema
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Validate custom business rules
|
|
7
|
-
* @param config Table configuration
|
|
8
|
-
* @returns Array of validation errors
|
|
9
|
-
*/
|
|
10
|
-
export function validateCustomRules(config) {
|
|
11
|
-
const errors = [];
|
|
12
|
-
if (!config.columns || !Array.isArray(config.columns)) {
|
|
13
|
-
return errors; // Let schema validation handle this
|
|
14
|
-
}
|
|
15
|
-
// 1. Check for duplicate column keys
|
|
16
|
-
const keys = config.columns.map(col => col.key);
|
|
17
|
-
const keyCounts = new Map();
|
|
18
|
-
keys.forEach((key, index) => {
|
|
19
|
-
const count = keyCounts.get(key) || 0;
|
|
20
|
-
keyCounts.set(key, count + 1);
|
|
21
|
-
if (count > 0) {
|
|
22
|
-
errors.push({
|
|
23
|
-
path: `/columns/${index}/key`,
|
|
24
|
-
message: `Duplicate column key: "${key}". Column keys must be unique.`,
|
|
25
|
-
code: 'DUPLICATE_KEY',
|
|
26
|
-
value: key,
|
|
27
|
-
field: `columns[${index}].key`
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
// 2. Validate width constraints for each column
|
|
32
|
-
config.columns.forEach((column, index) => {
|
|
33
|
-
const prefix = `/columns/${index}`;
|
|
34
|
-
// Width constraint: minWidth <= width <= maxWidth
|
|
35
|
-
if (typeof column.width === 'number' &&
|
|
36
|
-
column.minWidth !== undefined &&
|
|
37
|
-
column.width < column.minWidth) {
|
|
38
|
-
errors.push({
|
|
39
|
-
path: `${prefix}/width`,
|
|
40
|
-
message: `Width (${column.width}) must be greater than or equal to minWidth (${column.minWidth})`,
|
|
41
|
-
code: 'WIDTH_CONSTRAINT_VIOLATION',
|
|
42
|
-
value: column.width,
|
|
43
|
-
field: `columns[${index}].width`
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
if (typeof column.width === 'number' &&
|
|
47
|
-
column.maxWidth !== undefined &&
|
|
48
|
-
column.width > column.maxWidth) {
|
|
49
|
-
errors.push({
|
|
50
|
-
path: `${prefix}/width`,
|
|
51
|
-
message: `Width (${column.width}) must be less than or equal to maxWidth (${column.maxWidth})`,
|
|
52
|
-
code: 'WIDTH_CONSTRAINT_VIOLATION',
|
|
53
|
-
value: column.width,
|
|
54
|
-
field: `columns[${index}].width`
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
// 3. Sticky columns must have defined width (not 'auto')
|
|
58
|
-
if (column.sticky && (column.sticky === 'left' || column.sticky === 'right')) {
|
|
59
|
-
if (column.width === undefined || column.width === 'auto') {
|
|
60
|
-
errors.push({
|
|
61
|
-
path: `${prefix}/width`,
|
|
62
|
-
message: `Sticky columns must have a defined width (not 'auto'). Column "${column.key}" is sticky but has no width.`,
|
|
63
|
-
code: 'STICKY_WIDTH_REQUIRED',
|
|
64
|
-
value: column.width,
|
|
65
|
-
field: `columns[${index}].width`
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
// 4. Column key format validation (should be valid identifier)
|
|
70
|
-
if (column.key && !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(column.key)) {
|
|
71
|
-
errors.push({
|
|
72
|
-
path: `${prefix}/key`,
|
|
73
|
-
message: `Column key "${column.key}" must be a valid identifier (letters, numbers, underscore, dollar sign, starting with letter/underscore/dollar)`,
|
|
74
|
-
code: 'INVALID_KEY_FORMAT',
|
|
75
|
-
value: column.key,
|
|
76
|
-
field: `columns[${index}].key`
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
// 5. Validate pagination pageSize is in pageSizeOptions (if both provided)
|
|
81
|
-
if (config.pagination?.pageSize && config.pagination?.pageSizeOptions) {
|
|
82
|
-
if (!config.pagination.pageSizeOptions.includes(config.pagination.pageSize)) {
|
|
83
|
-
errors.push({
|
|
84
|
-
path: '/pagination/pageSize',
|
|
85
|
-
message: `pageSize (${config.pagination.pageSize}) must be one of the pageSizeOptions: [${config.pagination.pageSizeOptions.join(', ')}]`,
|
|
86
|
-
code: 'PAGE_SIZE_NOT_IN_OPTIONS',
|
|
87
|
-
value: config.pagination.pageSize,
|
|
88
|
-
field: 'pagination.pageSize'
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
// 6. Validate initial state sortBy keys exist in columns
|
|
93
|
-
if (config.initialState?.sortBy) {
|
|
94
|
-
const columnKeys = new Set(config.columns.map(col => col.key));
|
|
95
|
-
config.initialState.sortBy.forEach((sort, index) => {
|
|
96
|
-
if (!columnKeys.has(sort.key)) {
|
|
97
|
-
errors.push({
|
|
98
|
-
path: `/initialState/sortBy/${index}/key`,
|
|
99
|
-
message: `Sort key "${sort.key}" does not exist in columns`,
|
|
100
|
-
code: 'INVALID_SORT_KEY',
|
|
101
|
-
value: sort.key,
|
|
102
|
-
field: `initialState.sortBy[${index}].key`
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
// 7. Validate initial state filter keys exist in columns
|
|
108
|
-
if (config.initialState?.filters) {
|
|
109
|
-
const columnKeys = new Set(config.columns.map(col => col.key));
|
|
110
|
-
config.initialState.filters.forEach((filter, index) => {
|
|
111
|
-
if (!columnKeys.has(filter.key)) {
|
|
112
|
-
errors.push({
|
|
113
|
-
path: `/initialState/filters/${index}/key`,
|
|
114
|
-
message: `Filter key "${filter.key}" does not exist in columns`,
|
|
115
|
-
code: 'INVALID_FILTER_KEY',
|
|
116
|
-
value: filter.key,
|
|
117
|
-
field: `initialState.filters[${index}].key`
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
return errors;
|
|
123
|
-
}
|
|
124
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tLXZhbGlkYXRpb24tcnVsZXMudXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NtYXJ0LXRhYmxlL3NyYy9saWIvc2VydmljZXMvY3VzdG9tLXZhbGlkYXRpb24tcnVsZXMudXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFLSDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQixDQUFDLE1BQW1CO0lBQ3JELE1BQU0sTUFBTSxHQUE0QixFQUFFLENBQUM7SUFFM0MsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRTtRQUNyRCxPQUFPLE1BQU0sQ0FBQyxDQUFDLG9DQUFvQztLQUNwRDtJQUVELHFDQUFxQztJQUNyQyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNoRCxNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUM1QyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFO1FBQzFCLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3RDLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztRQUM5QixJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUU7WUFDYixNQUFNLENBQUMsSUFBSSxDQUFDO2dCQUNWLElBQUksRUFBRSxZQUFZLEtBQUssTUFBTTtnQkFDN0IsT0FBTyxFQUFFLDBCQUEwQixHQUFHLGdDQUFnQztnQkFDdEUsSUFBSSxFQUFFLGVBQWU7Z0JBQ3JCLEtBQUssRUFB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RyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQy9ELE1BQU0sQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsRUFBRTtZQUNwRCxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUU7Z0JBQy9CLE1BQU0sQ0FBQyxJQUFJLENBQUM7b0JBQ1YsSUFBSSxFQUFFLHlCQUF5QixLQUFLLE1BQU07b0JBQzFDLE9BQU8sRUFBRSxlQUFlLE1BQU0sQ0FBQyxHQUFHLDZCQUE2QjtvQkFDL0QsSUFBSSxFQUFFLG9CQUFvQjtvQkFDMUIsS0FBSyxFQUFFLE1BQU0sQ0FBQyxHQUFHO29CQUNqQixLQUFLLEVBQUUsd0JBQXdCLEtBQUssT0FBTztpQkFDNUMsQ0FBQyxDQUFDO2FBQ0o7UUFDSCxDQUFDLENBQUMsQ0FBQztLQUNKO0lBRUQsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ3VzdG9tIHZhbGlkYXRpb24gcnVsZXMgdXRpbGl0eVxuICogSW1wbGVtZW50cyBidXNpbmVzcyBsb2dpYyB2YWxpZGF0aW9ucyB0aGF0IGNhbid0IGJlIGV4cHJlc3NlZCBpbiBKU09OIFNjaGVtYVxuICovXG5cbmltcG9ydCB7IFRhYmxlQ29uZmlnIH0gZnJvbSAnLi4vbW9kZWxzL3RhYmxlLWNvbmZpZy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgU2NoZW1hVmFsaWRhdGlvbkVycm9yIH0gZnJvbSAnLi4vbW9kZWxzL3NjaGVtYS12YWxpZGF0aW9uLmludGVyZmFjZSc7XG5cbi8qKlxuICogVmFsaWRhdGUgY3VzdG9tIGJ1c2luZXNzIHJ1bGVzXG4gKiBAcGFyYW0gY29uZmlnIFRhYmxlIGNvbmZpZ3VyYXRpb25cbiAqIEByZXR1cm5zIEFycmF5IG9mIHZhbGlkYXRpb24gZXJyb3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUN1c3RvbVJ1bGVzKGNvbmZpZzogVGFibGVDb25maWcpOiBTY2hlbWFWYWxpZGF0aW9uRXJyb3JbXSB7XG4gIGNvbnN0IGVycm9yczogU2NoZW1hVmFsaWRhdGlvbkVycm9yW10gPSBbXTtcblxuICBpZiAoIWNvbmZpZy5jb2x1bW5zIHx8ICFBcnJheS5pc0FycmF5KGNvbmZpZy5jb2x1bW5zKSkge1xuICAgIHJldHVybiBlcnJvcnM7IC8vIExldCBzY2hlbWEgdmFsaWRhdGlvbiBoYW5kbGUgdGhpc1xuICB9XG5cbiAgLy8gMS4gQ2hlY2sgZm9yIGR1cGxpY2F0ZSBjb2x1bW4ga2V5c1xuICBjb25zdCBrZXlzID0gY29uZmlnLmNvbHVtbnMubWFwKGNvbCA9PiBjb2wua2V5KTtcbiAgY29uc3Qga2V5Q291bnRzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAga2V5cy5mb3JFYWNoKChrZXksIGluZGV4KSA9PiB7XG4gICAgY29uc3QgY291bnQgPSBrZXlDb3VudHMuZ2V0KGtleSkgfHwgMDtcbiAgICBrZXlDb3VudHMuc2V0KGtleSwgY291bnQgKyAxKTtcbiAgICBpZiAoY291bnQgPiAwKSB7XG4gICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgIHBhdGg6IGAvY29sdW1ucy8ke2luZGV4fS9rZXlgLFxuICAgICAgICBtZXNzYWdlOiBgRHVwbGljYXRlIGNvbHVtbiBrZXk6IFwiJHtrZXl9XCIuIENvbHVtbiBrZXlzIG11c3QgYmUgdW5pcXVlLmAsXG4gICAgICAgIGNvZGU6ICdEVVBMSUNBVEVfS0VZJyxcbiAgICAgICAgdmFsdWU6IGtleSxcbiAgICAgICAgZmllbGQ6IGBjb2x1bW5zWyR7aW5kZXh9XS5rZXlgXG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIDIuIFZhbGlkYXRlIHdpZHRoIGNvbnN0cmFpbnRzIGZvciBlYWNoIGNvbHVtblxuICBjb25maWcuY29sdW1ucy5mb3JFYWNoKChjb2x1bW4sIGluZGV4KSA9PiB7XG4gICAgY29uc3QgcHJlZml4ID0gYC9jb2x1bW5zLyR7aW5kZXh9YDtcbiAgICBcbiAgICAvLyBXaWR0aCBjb25zdHJhaW50OiBtaW5XaWR0aCA8PSB3aWR0aCA8PSBtYXhXaWR0aFxuICAgIGlmIChcbiAgICAgIHR5cGVvZiBjb2x1bW4ud2lkdGggPT09ICdudW1iZXInICYmXG4gICAgICBjb2x1bW4ubWluV2lkdGggIT09IHVuZGVmaW5lZCAmJlxuICAgICAgY29sdW1uLndpZHRoIDwgY29sdW1uLm1pbldpZHRoXG4gICAgKSB7XG4gICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgIHBhdGg6IGAke3ByZWZpeH0vd2lkdGhgLFxuICAgICAgICBtZXNzYWdlOiBgV2lkdGggKCR7Y29sdW1uLndpZHRofSkgbXVzdCBiZSBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gbWluV2lkdGggKCR7Y29sdW1uLm1pbldpZHRofSlgLFxuICAgICAgICBjb2RlOiAnV0lEVEhfQ09OU1RSQUlOVF9WSU9MQVRJT04nLFxuICAgICAgICB2YWx1ZTogY29sdW1uLndpZHRoLFxuICAgICAgICBmaWVsZDogYGNvbHVtbnNbJHtpbmRleH1dLndpZHRoYFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdHlwZW9mIGNvbHVtbi53aWR0aCA9PT0gJ251bWJlcicgJiZcbiAgICAgIGNvbHVtbi5tYXhXaWR0aCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICBjb2x1bW4ud2lkdGggPiBjb2x1bW4ubWF4V2lkdGhcbiAgICApIHtcbiAgICAgIGVycm9ycy5wdXNoKHtcbiAgICAgICAgcGF0aDogYCR7cHJlZml4fS93aWR0aGAsXG4gICAgICAgIG1lc3NhZ2U6IGBXaWR0aCAoJHtjb2x1bW4ud2lkdGh9KSBtdXN0IGJlIGxlc3MgdGhhbiBvciBlcXVhbCB0byBtYXhXaWR0aCAoJHtjb2x1bW4ubWF4V2lkdGh9KWAsXG4gICAgICAgIGNvZGU6ICdXSURUSF9DT05TVFJBSU5UX1ZJT0xBVElPTicsXG4gICAgICAgIHZhbHVlOiBjb2x1bW4ud2lkdGgsXG4gICAgICAgIGZpZWxkOiBgY29sdW1uc1ske2luZGV4fV0ud2lkdGhgXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyAzLiBTdGlja3kgY29sdW1ucyBtdXN0IGhhdmUgZGVmaW5lZCB3aWR0aCAobm90ICdhdXRvJylcbiAgICBpZiAoY29sdW1uLnN0aWNreSAmJiAoY29sdW1uLnN0aWNreSA9PT0gJ2xlZnQnIHx8IGNvbHVtbi5zdGlja3kgPT09ICdyaWdodCcpKSB7XG4gICAgICBpZiAoY29sdW1uLndpZHRoID09PSB1bmRlZmluZWQgfHwgY29sdW1uLndpZHRoID09PSAnYXV0bycpIHtcbiAgICAgICAgZXJyb3JzLnB1c2goe1xuICAgICAgICAgIHBhdGg6IGAke3ByZWZpeH0vd2lkdGhgLFxuICAgICAgICAgIG1lc3NhZ2U6IGBTdGlja3kgY29sdW1ucyBtdXN0IGhhdmUgYSBkZWZpbmVkIHdpZHRoIChub3QgJ2F1dG8nKS4gQ29sdW1uIFwiJHtjb2x1bW4ua2V5fVwiIGlzIHN0aWNreSBidXQgaGFzIG5vIHdpZHRoLmAsXG4gICAgICAgICAgY29kZTogJ1NUSUNLWV9XSURUSF9SRVFVSVJFRCcsXG4gICAgICAgICAgdmFsdWU6IGNvbHVtbi53aWR0aCxcbiAgICAgICAgICBmaWVsZDogYGNvbHVtbnNbJHtpbmRleH1dLndpZHRoYFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyA0LiBDb2x1bW4ga2V5IGZvcm1hdCB2YWxpZGF0aW9uIChzaG91bGQgYmUgdmFsaWQgaWRlbnRpZmllcilcbiAgICBpZiAoY29sdW1uLmtleSAmJiAhL15bYS16QS1aXyRdW2EtekEtWjAtOV8kXSokLy50ZXN0KGNvbHVtbi5rZXkpKSB7XG4gICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgIHBhdGg6IGAke3ByZWZpeH0va2V5YCxcbiAgICAgICAgbWVzc2FnZTogYENvbHVtbiBrZXkgXCIke2NvbHVtbi5rZXl9XCIgbXVzdCBiZSBhIHZhbGlkIGlkZW50aWZpZXIgKGxldHRlcnMsIG51bWJlcnMsIHVuZGVyc2NvcmUsIGRvbGxhciBzaWduLCBzdGFydGluZyB3aXRoIGxldHRlci91bmRlcnNjb3JlL2RvbGxhcilgLFxuICAgICAgICBjb2RlOiAnSU5WQUxJRF9LRVlfRk9STUFUJyxcbiAgICAgICAgdmFsdWU6IGNvbHVtbi5rZXksXG4gICAgICAgIGZpZWxkOiBgY29sdW1uc1ske2luZGV4fV0ua2V5YFxuICAgICAgfSk7XG4gICAgfVxuICB9KTtcblxuICAvLyA1LiBWYWxpZGF0ZSBwYWdpbmF0aW9uIHBhZ2VTaXplIGlzIGluIHBhZ2VTaXplT3B0aW9ucyAoaWYgYm90aCBwcm92aWRlZClcbiAgaWYgKGNvbmZpZy5wYWdpbmF0aW9uPy5wYWdlU2l6ZSAmJiBjb25maWcucGFnaW5hdGlvbj8ucGFnZVNpemVPcHRpb25zKSB7XG4gICAgaWYgKCFjb25maWcucGFnaW5hdGlvbi5wYWdlU2l6ZU9wdGlvbnMuaW5jbHVkZXMoY29uZmlnLnBhZ2luYXRpb24ucGFnZVNpemUpKSB7XG4gICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgIHBhdGg6ICcvcGFnaW5hdGlvbi9wYWdlU2l6ZScsXG4gICAgICAgIG1lc3NhZ2U6IGBwYWdlU2l6ZSAoJHtjb25maWcucGFnaW5hdGlvbi5wYWdlU2l6ZX0pIG11c3QgYmUgb25lIG9mIHRoZSBwYWdlU2l6ZU9wdGlvbnM6IFske2NvbmZpZy5wYWdpbmF0aW9uLnBhZ2VTaXplT3B0aW9ucy5qb2luKCcsICcpfV1gLFxuICAgICAgICBjb2RlOiAnUEFHRV9TSVpFX05PVF9JTl9PUFRJT05TJyxcbiAgICAgICAgdmFsdWU6IGNvbmZpZy5wYWdpbmF0aW9uLnBhZ2VTaXplLFxuICAgICAgICBmaWVsZDogJ3BhZ2luYXRpb24ucGFnZVNpemUnXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvLyA2LiBWYWxpZGF0ZSBpbml0aWFsIHN0YXRlIHNvcnRCeSBrZXlzIGV4aXN0IGluIGNvbHVtbnNcbiAgaWYgKGNvbmZpZy5pbml0aWFsU3RhdGU/LnNvcnRCeSkge1xuICAgIGNvbnN0IGNvbHVtbktleXMgPSBuZXcgU2V0KGNvbmZpZy5jb2x1bW5zLm1hcChjb2wgPT4gY29sLmtleSkpO1xuICAgIGNvbmZpZy5pbml0aWFsU3RhdGUuc29ydEJ5LmZvckVhY2goKHNvcnQsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoIWNvbHVtbktleXMuaGFzKHNvcnQua2V5KSkge1xuICAgICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgICAgcGF0aDogYC9pbml0aWFsU3RhdGUvc29ydEJ5LyR7aW5kZXh9L2tleWAsXG4gICAgICAgICAgbWVzc2FnZTogYFNvcnQga2V5IFwiJHtzb3J0LmtleX1cIiBkb2VzIG5vdCBleGlzdCBpbiBjb2x1bW5zYCxcbiAgICAgICAgICBjb2RlOiAnSU5WQUxJRF9TT1JUX0tFWScsXG4gICAgICAgICAgdmFsdWU6IHNvcnQua2V5LFxuICAgICAgICAgIGZpZWxkOiBgaW5pdGlhbFN0YXRlLnNvcnRCeVske2luZGV4fV0ua2V5YFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIDcuIFZhbGlkYXRlIGluaXRpYWwgc3RhdGUgZmlsdGVyIGtleXMgZXhpc3QgaW4gY29sdW1uc1xuICBpZiAoY29uZmlnLmluaXRpYWxTdGF0ZT8uZmlsdGVycykge1xuICAgIGNvbnN0IGNvbHVtbktleXMgPSBuZXcgU2V0KGNvbmZpZy5jb2x1bW5zLm1hcChjb2wgPT4gY29sLmtleSkpO1xuICAgIGNvbmZpZy5pbml0aWFsU3RhdGUuZmlsdGVycy5mb3JFYWNoKChmaWx0ZXIsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoIWNvbHVtbktleXMuaGFzKGZpbHRlci5rZXkpKSB7XG4gICAgICAgIGVycm9ycy5wdXNoKHtcbiAgICAgICAgICBwYXRoOiBgL2luaXRpYWxTdGF0ZS9maWx0ZXJzLyR7aW5kZXh9L2tleWAsXG4gICAgICAgICAgbWVzc2FnZTogYEZpbHRlciBrZXkgXCIke2ZpbHRlci5rZXl9XCIgZG9lcyBub3QgZXhpc3QgaW4gY29sdW1uc2AsXG4gICAgICAgICAgY29kZTogJ0lOVkFMSURfRklMVEVSX0tFWScsXG4gICAgICAgICAgdmFsdWU6IGZpbHRlci5rZXksXG4gICAgICAgICAgZmllbGQ6IGBpbml0aWFsU3RhdGUuZmlsdGVyc1ske2luZGV4fV0ua2V5YFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBlcnJvcnM7XG59XG5cbiJdfQ==
|
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* JSON Schema Validation Service
|
|
3
|
-
* Validates TableConfig JSON against JSON Schema using ajv
|
|
4
|
-
*
|
|
5
|
-
*/
|
|
6
|
-
import { Injectable } from '@angular/core';
|
|
7
|
-
import { tableConfigSchema } from '../schemas/table-config.schema';
|
|
8
|
-
import { validateCustomRules } from './custom-validation-rules.util';
|
|
9
|
-
import Ajv from 'ajv';
|
|
10
|
-
import * as i0 from "@angular/core";
|
|
11
|
-
import * as i1 from "./validation-logger.service";
|
|
12
|
-
export class JsonSchemaValidatorService {
|
|
13
|
-
constructor(logger) {
|
|
14
|
-
this.logger = logger;
|
|
15
|
-
this.ajv = null;
|
|
16
|
-
this.validateFn = null;
|
|
17
|
-
this.ajvAvailable = false;
|
|
18
|
-
this.initialized = false;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Ensure ajv is initialized (lazy initialization)
|
|
22
|
-
*/
|
|
23
|
-
ensureInitialized() {
|
|
24
|
-
if (!this.initialized) {
|
|
25
|
-
this.initializeAjv();
|
|
26
|
-
this.initialized = true;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Initialize ajv validator
|
|
31
|
-
*/
|
|
32
|
-
initializeAjv() {
|
|
33
|
-
try {
|
|
34
|
-
// Try to load ajv - use require for compatibility with Angular build system
|
|
35
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
36
|
-
this.ajv = new Ajv({
|
|
37
|
-
allErrors: true,
|
|
38
|
-
verbose: true,
|
|
39
|
-
strict: false,
|
|
40
|
-
validateSchema: false // Don't validate the schema itself
|
|
41
|
-
});
|
|
42
|
-
// Compile schema (convert const to regular object for ajv)
|
|
43
|
-
const schema = JSON.parse(JSON.stringify(tableConfigSchema));
|
|
44
|
-
this.validateFn = this.ajv.compile(schema);
|
|
45
|
-
this.ajvAvailable = true;
|
|
46
|
-
}
|
|
47
|
-
catch (error) {
|
|
48
|
-
// ajv is optional - if not installed, validation will use custom rules only
|
|
49
|
-
console.warn('ajv library not found. JSON schema validation will be disabled. Install with: npm install ajv');
|
|
50
|
-
this.ajvAvailable = false;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Validate JSON data against TableConfig schema
|
|
55
|
-
* @param data JSON data to validate
|
|
56
|
-
* @param includeCustomRules Whether to include custom business rule validations
|
|
57
|
-
* @param enableLogging Whether to log validation errors (default: true)
|
|
58
|
-
* @returns Validation result
|
|
59
|
-
*/
|
|
60
|
-
validate(data, includeCustomRules = true, enableLogging = true) {
|
|
61
|
-
// Ensure ajv is initialized before validation
|
|
62
|
-
this.ensureInitialized();
|
|
63
|
-
const allErrors = [];
|
|
64
|
-
// 1. JSON Schema validation (if ajv is available)
|
|
65
|
-
if (this.ajvAvailable) {
|
|
66
|
-
const isValid = this.validateFn(data);
|
|
67
|
-
if (!isValid) {
|
|
68
|
-
// Convert ajv errors to our format
|
|
69
|
-
const schemaErrors = (this.validateFn.errors || []).map((error) => {
|
|
70
|
-
const path = error.instancePath || error.schemaPath || '';
|
|
71
|
-
const field = this.pathToFieldName(path);
|
|
72
|
-
return {
|
|
73
|
-
path: path,
|
|
74
|
-
message: this.formatErrorMessage(error, field),
|
|
75
|
-
code: error.keyword || 'VALIDATION_ERROR',
|
|
76
|
-
value: error.data,
|
|
77
|
-
field: field
|
|
78
|
-
};
|
|
79
|
-
});
|
|
80
|
-
allErrors.push(...schemaErrors);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
// If ajv is not available, add a warning but continue with custom rules
|
|
85
|
-
allErrors.push({
|
|
86
|
-
path: '',
|
|
87
|
-
message: 'JSON schema validation is not available. Please install ajv: npm install ajv',
|
|
88
|
-
code: 'AJV_NOT_AVAILABLE',
|
|
89
|
-
field: 'root'
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
// 2. Custom business rule validation
|
|
93
|
-
if (includeCustomRules && data && typeof data === 'object') {
|
|
94
|
-
try {
|
|
95
|
-
const customErrors = validateCustomRules(data);
|
|
96
|
-
allErrors.push(...customErrors);
|
|
97
|
-
}
|
|
98
|
-
catch (error) {
|
|
99
|
-
allErrors.push({
|
|
100
|
-
path: '',
|
|
101
|
-
message: `Custom validation failed: ${error.message}`,
|
|
102
|
-
code: 'CUSTOM_VALIDATION_ERROR',
|
|
103
|
-
field: 'root'
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
const result = {
|
|
108
|
-
valid: allErrors.length === 0,
|
|
109
|
-
errors: allErrors,
|
|
110
|
-
ajvAvailable: this.ajvAvailable
|
|
111
|
-
};
|
|
112
|
-
// Log validation errors if validation failed and logging is enabled
|
|
113
|
-
if (!result.valid && enableLogging) {
|
|
114
|
-
this.logger.logValidationErrors(allErrors, 'schema-validation');
|
|
115
|
-
}
|
|
116
|
-
return result;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Validate JSON string
|
|
120
|
-
* @param jsonString JSON string to validate
|
|
121
|
-
* @param includeCustomRules Whether to include custom business rule validations
|
|
122
|
-
* @param enableLogging Whether to log validation errors (default: true)
|
|
123
|
-
* @returns Validation result
|
|
124
|
-
*/
|
|
125
|
-
validateJSONString(jsonString, includeCustomRules = true, enableLogging = true) {
|
|
126
|
-
try {
|
|
127
|
-
const data = JSON.parse(jsonString);
|
|
128
|
-
return this.validate(data, includeCustomRules, enableLogging);
|
|
129
|
-
}
|
|
130
|
-
catch (error) {
|
|
131
|
-
const result = {
|
|
132
|
-
valid: false,
|
|
133
|
-
errors: [{
|
|
134
|
-
path: '',
|
|
135
|
-
message: `Invalid JSON: ${error.message}`,
|
|
136
|
-
code: 'JSON_PARSE_ERROR',
|
|
137
|
-
value: jsonString,
|
|
138
|
-
field: 'root'
|
|
139
|
-
}],
|
|
140
|
-
ajvAvailable: this.ajvAvailable
|
|
141
|
-
};
|
|
142
|
-
// Log JSON parse errors if logging is enabled
|
|
143
|
-
if (enableLogging) {
|
|
144
|
-
this.logger.logValidationErrors(result.errors, 'schema-validation', {
|
|
145
|
-
configSnippet: jsonString.substring(0, 200) // Include first 200 chars as context
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
return result;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
/**
|
|
152
|
-
* Check if ajv is available
|
|
153
|
-
*/
|
|
154
|
-
isAvailable() {
|
|
155
|
-
this.ensureInitialized();
|
|
156
|
-
return this.ajvAvailable;
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Convert JSON path to user-friendly field name
|
|
160
|
-
*/
|
|
161
|
-
pathToFieldName(path) {
|
|
162
|
-
if (!path)
|
|
163
|
-
return 'root';
|
|
164
|
-
// Remove leading slash
|
|
165
|
-
let field = path.replace(/^\//, '');
|
|
166
|
-
// Replace array indices with brackets
|
|
167
|
-
field = field.replace(/\/(\d+)/g, '[$1]');
|
|
168
|
-
// Replace slashes with dots
|
|
169
|
-
field = field.replace(/\//g, '.');
|
|
170
|
-
return field || 'root';
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Format error message from ajv error
|
|
174
|
-
*/
|
|
175
|
-
formatErrorMessage(error, field) {
|
|
176
|
-
const keyword = error.keyword;
|
|
177
|
-
const params = error.params || {};
|
|
178
|
-
switch (keyword) {
|
|
179
|
-
case 'required':
|
|
180
|
-
return `Field '${field}' is required but missing`;
|
|
181
|
-
case 'type':
|
|
182
|
-
return `Field '${field}' must be of type ${params.type}, but got ${typeof error.data}`;
|
|
183
|
-
case 'enum':
|
|
184
|
-
return `Field '${field}' must be one of: ${params.allowedValues?.join(', ') || 'allowed values'}`;
|
|
185
|
-
case 'pattern':
|
|
186
|
-
return `Field '${field}' does not match required pattern: ${params.pattern}`;
|
|
187
|
-
case 'minimum':
|
|
188
|
-
return `Field '${field}' must be at least ${params.limit}`;
|
|
189
|
-
case 'maximum':
|
|
190
|
-
return `Field '${field}' must be at most ${params.limit}`;
|
|
191
|
-
case 'minLength':
|
|
192
|
-
return `Field '${field}' must have at least ${params.limit} items`;
|
|
193
|
-
case 'maxLength':
|
|
194
|
-
return `Field '${field}' must have at most ${params.limit} items`;
|
|
195
|
-
case 'minItems':
|
|
196
|
-
return `Array '${field}' must have at least ${params.limit} items`;
|
|
197
|
-
case 'maxItems':
|
|
198
|
-
return `Array '${field}' must have at most ${params.limit} items`;
|
|
199
|
-
case 'additionalProperties':
|
|
200
|
-
return `Field '${field}' contains unknown property: ${params.additionalProperty}`;
|
|
201
|
-
case 'oneOf':
|
|
202
|
-
return `Field '${field}' does not match any of the allowed types`;
|
|
203
|
-
default:
|
|
204
|
-
return error.message || `Field '${field}' is invalid`;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
JsonSchemaValidatorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: JsonSchemaValidatorService, deps: [{ token: i1.ValidationLoggerService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
209
|
-
JsonSchemaValidatorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: JsonSchemaValidatorService, providedIn: 'root' });
|
|
210
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: JsonSchemaValidatorService, decorators: [{
|
|
211
|
-
type: Injectable,
|
|
212
|
-
args: [{
|
|
213
|
-
providedIn: 'root'
|
|
214
|
-
}]
|
|
215
|
-
}], ctorParameters: function () { return [{ type: i1.ValidationLoggerService }]; } });
|
|
216
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi1zY2hlbWEtdmFsaWRhdG9yLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zbWFydC10YWJsZS9zcmMvbGliL3NlcnZpY2VzL2pzb24tc2NoZW1hLXZhbGlkYXRvci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBR3JFLE9BQU8sR0FBRyxNQUFNLEtBQUssQ0FBQzs7O0FBTXRCLE1BQU0sT0FBTywwQkFBMEI7SUFNckMsWUFBb0IsTUFBK0I7UUFBL0IsV0FBTSxHQUFOLE1BQU0sQ0FBeUI7UUFMM0MsUUFBRyxHQUFRLElBQUksQ0FBQztRQUNoQixlQUFVLEdBQVEsSUFBSSxDQUFDO1FBQ3ZCLGlCQUFZLEdBQVksS0FBSyxDQUFDO1FBQzlCLGdCQUFXLEdBQVksS0FBSyxDQUFDO0lBR3JDLENBQUM7SUFFRDs7T0FFRztJQUNLLGlCQUFpQjtRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNyQixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7U0FDekI7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxhQUFhO1FBQ25CLElBQUk7WUFDRiw0RUFBNEU7WUFDNUUsdUVBQXVFO1lBQ3ZFLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxHQUFHLENBQUM7Z0JBQ2pCLFNBQVMsRUFBRSxJQUFJO2dCQUNmLE9BQU8sRUFBRSxJQUFJO2dCQUNiLE1BQU0sRUFBRSxLQUFLO2dCQUNiLGNBQWMsRUFBRSxLQUFLLENBQUMsbUNBQW1DO2FBQzFELENBQUMsQ0FBQztZQUVILDJEQUEyRDtZQUMzRCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDO1lBQzdELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDM0MsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUM7U0FDMUI7UUFBQyxPQUFPLEtBQUssRUFBRTtZQUNkLDRFQUE0RTtZQUM1RSxPQUFPLENBQUMsSUFBSSxDQUFDLCtGQUErRixDQUFDLENBQUM7WUFDOUcsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7U0FDM0I7SUFDSCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsUUFBUSxDQUFDLElBQVMsRUFBRSxxQkFBOEIsSUFBSSxFQUFFLGdCQUF5QixJQUFJO1FBQ25GLDhDQUE4QztRQUM5QyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztRQUV6QixNQUFNLFNBQVMsR0FBNEIsRUFBRSxDQUFDO1FBRTlDLGtEQUFrRDtRQUNsRCxJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUU7WUFDckIsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUV0QyxJQUFJLENBQUMsT0FBTyxFQUFFO2dCQUNaLG1DQUFtQztnQkFDbkMsTUFBTSxZQUFZLEdBQTRCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBVSxFQUFFLEVBQUU7b0JBQzlGLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxZQUFZLElBQUksS0FBSyxDQUFDLFVBQVUsSUFBSSxFQUFFLENBQUM7b0JBQzFELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBRXpDLE9BQU87d0JBQ0wsSUFBSSxFQUFFLElBQUk7d0JBQ1YsT0FBTyxFQUFFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDO3dCQUM5QyxJQUFJLEVBQUUsS0FBSyxDQUFDLE9BQU8sSUFBSSxrQkFBa0I7d0JBQ3pDLEtBQUssRUFBRSxLQUFLLENBQUMsSUFBSTt3QkFDakIsS0FBSyxFQUFFLEtBQUs7cUJBQ2IsQ0FBQztnQkFDSixDQUFDLENBQUMsQ0FBQztnQkFFSCxTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsWUFBWSxDQUFDLENBQUM7YUFDakM7U0FDRjthQUFNO1lBQ0wsd0VBQXdFO1lBQ3hFLFNBQVMsQ0FBQyxJQUFJLENBQUM7Z0JBQ2IsSUFBSSxFQUFFLEVBQUU7Z0JBQ1IsT0FBTyxFQUFFLDhFQUE4RTtnQkFDdkYsSUFBSSxFQUFFLG1CQUFtQjtnQkFDekIsS0FBSyxFQUFFLE1BQU07YUFDZCxDQUFDLENBQUM7U0FDSjtRQUVELHFDQUFxQztRQUNyQyxJQUFJLGtCQUFrQixJQUFJLElBQUksSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLEVBQUU7WUFDMUQsSUFBSTtnQkFDRixNQUFNLFlBQVksR0FBRyxtQkFBbUIsQ0FBQyxJQUFXLENBQUMsQ0FBQztnQkFDdEQsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLFlBQVksQ0FBQyxDQUFDO2FBQ2pDO1lBQUMsT0FBTyxLQUFVLEVBQUU7Z0JBQ25CLFNBQVMsQ0FBQyxJQUFJLENBQUM7b0JBQ2IsSUFBSSxFQUFFLEVBQUU7b0JBQ1IsT0FBTyxFQUFFLDZCQUE2QixLQUFLLENBQUMsT0FBTyxFQUFFO29CQUNyRCxJQUFJLEVBQUUseUJBQXlCO29CQUMvQixLQUFLLEVBQUUsTUFBTTtpQkFDZCxDQUFDLENBQUM7YUFDSjtTQUNGO1FBRUQsTUFBTSxNQUFNLEdBQUc7WUFDYixLQUFLLEVBQUUsU0FBUyxDQUFDLE1BQU0sS0FBSyxDQUFDO1lBQzdCLE1BQU0sRUFBRSxTQUFTO1lBQ2pCLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWTtTQUNoQyxDQUFDO1FBRUYsb0VBQW9FO1FBQ3BFLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxJQUFJLGFBQWEsRUFBRTtZQUNsQyxJQUFJLENBQUMsTUFBTSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1NBQ2pFO1FBRUQsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILGtCQUFrQixDQUFDLFVBQWtCLEVBQUUscUJBQThCLElBQUksRUFBRSxnQkFBeUIsSUFBSTtRQUN0RyxJQUFJO1lBQ0YsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNwQyxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLGtCQUFrQixFQUFFLGFBQWEsQ0FBQyxDQUFDO1NBQy9EO1FBQUMsT0FBTyxLQUFVLEVBQUU7WUFDbkIsTUFBTSxNQUFNLEdBQUc7Z0JBQ2IsS0FBSyxFQUFFLEtBQUs7Z0JBQ1osTUFBTSxFQUFFLENBQUM7d0JBQ1AsSUFBSSxFQUFFLEVBQUU7d0JBQ1IsT0FBTyxFQUFFLGlCQUFpQixLQUFLLENBQUMsT0FBTyxFQUFFO3dCQUN6QyxJQUFJLEVBQUUsa0JBQWtCO3dCQUN4QixLQUFLLEVBQUUsVUFBVTt3QkFDakIsS0FBSyxFQUFFLE1BQU07cUJBQ2QsQ0FBQztnQkFDRixZQUFZLEVBQUUsSUFBSSxDQUFDLFlBQVk7YUFDaEMsQ0FBQztZQUVGLDhDQUE4QztZQUM5QyxJQUFJLGFBQWEsRUFBRTtnQkFDakIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLG1CQUFtQixFQUFFO29CQUNsRSxhQUFhLEVBQUUsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMscUNBQXFDO2lCQUNsRixDQUFDLENBQUM7YUFDSjtZQUVELE9BQU8sTUFBTSxDQUFDO1NBQ2Y7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxXQUFXO1FBQ1QsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDekIsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQzNCLENBQUM7SUFFRDs7T0FFRztJQUNLLGVBQWUsQ0FBQyxJQUFZO1FBQ2xDLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTyxNQUFNLENBQUM7UUFFekIsdUJBQXVCO1FBQ3ZCLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRXBDLHNDQUFzQztRQUN0QyxLQUFLLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFMUMsNEJBQTRCO1FBQzVCLEtBQUssR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztRQUVsQyxPQUFPLEtBQUssSUFBSSxNQUFNLENBQUM7SUFDekIsQ0FBQztJQUVEOztPQUVHO0lBQ0ssa0JBQWtCLENBQUMsS0FBVSxFQUFFLEtBQWE7UUFDbEQsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztRQUM5QixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQztRQUVsQyxRQUFRLE9BQU8sRUFBRTtZQUNmLEtBQUssVUFBVTtnQkFDYixPQUFPLFVBQVUsS0FBSywyQkFBMkIsQ0FBQztZQUVwRCxLQUFLLE1BQU07Z0JBQ1QsT0FBTyxVQUFVLEtBQUsscUJBQXFCLE1BQU0sQ0FBQyxJQUFJLGFBQWEsT0FBTyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7WUFFekYsS0FBSyxNQUFNO2dCQUNULE9BQU8sVUFBVSxLQUFLLHFCQUFxQixNQUFNLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1lBRXBHLEtBQUssU0FBUztnQkFDWixPQUFPLFVBQVUsS0FBSyxzQ0FBc0MsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBRS9FLEtBQUssU0FBUztnQkFDWixPQUFPLFVBQVUsS0FBSyxzQkFBc0IsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBRTdELEtBQUssU0FBUztnQkFDWixPQUFPLFVBQVUsS0FBSyxxQkFBcUIsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBRTVELEtBQUssV0FBVztnQkFDZCxPQUFPLFVBQVUsS0FBSyx3QkFBd0IsTUFBTSxDQUFDLEtBQUssUUFBUSxDQUFDO1lBRXJFLEtBQUssV0FBVztnQkFDZCxPQUFPLFVBQVUsS0FBSyx1QkFBdUIsTUFBTSxDQUFDLEtBQUssUUFBUSxDQUFDO1lBRXBFLEtBQUssVUFBVTtnQkFDYixPQUFPLFVBQVUsS0FBSyx3QkFBd0IsTUFBTSxDQUFDLEtBQUssUUFBUSxDQUFDO1lBRXJFLEtBQUssVUFBVTtnQkFDYixPQUFPLFVBQVUsS0FBSyx1QkFBdUIsTUFBTSxDQUFDLEtBQUssUUFBUSxDQUFDO1lBRXBFLEtBQUssc0JBQXNCO2dCQUN6QixPQUFPLFVBQVUsS0FBSyxnQ0FBZ0MsTUFBTSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFFcEYsS0FBSyxPQUFPO2dCQUNWLE9BQU8sVUFBVSxLQUFLLDJDQUEyQyxDQUFDO1lBRXBFO2dCQUNFLE9BQU8sS0FBSyxDQUFDLE9BQU8sSUFBSSxVQUFVLEtBQUssY0FBYyxDQUFDO1NBQ3pEO0lBQ0gsQ0FBQzs7dUhBak9VLDBCQUEwQjsySEFBMUIsMEJBQTBCLGNBRnpCLE1BQU07MkZBRVAsMEJBQTBCO2tCQUh0QyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogSlNPTiBTY2hlbWEgVmFsaWRhdGlvbiBTZXJ2aWNlXG4gKiBWYWxpZGF0ZXMgVGFibGVDb25maWcgSlNPTiBhZ2FpbnN0IEpTT04gU2NoZW1hIHVzaW5nIGFqdlxuICogXG4gKi9cblxuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFibGVDb25maWdTY2hlbWEgfSBmcm9tICcuLi9zY2hlbWFzL3RhYmxlLWNvbmZpZy5zY2hlbWEnO1xuaW1wb3J0IHsgdmFsaWRhdGVDdXN0b21SdWxlcyB9IGZyb20gJy4vY3VzdG9tLXZhbGlkYXRpb24tcnVsZXMudXRpbCc7XG5pbXBvcnQgeyBWYWxpZGF0aW9uTG9nZ2VyU2VydmljZSB9IGZyb20gJy4vdmFsaWRhdGlvbi1sb2dnZXIuc2VydmljZSc7XG5pbXBvcnQgeyBTY2hlbWFWYWxpZGF0aW9uRXJyb3IsIFNjaGVtYVZhbGlkYXRpb25SZXN1bHQgfSBmcm9tICcuLi9tb2RlbHMvc2NoZW1hLXZhbGlkYXRpb24uaW50ZXJmYWNlJztcbmltcG9ydCBBanYgZnJvbSAnYWp2JztcblxuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBKc29uU2NoZW1hVmFsaWRhdG9yU2VydmljZSB7XG4gIHByaXZhdGUgYWp2OiBhbnkgPSBudWxsO1xuICBwcml2YXRlIHZhbGlkYXRlRm46IGFueSA9IG51bGw7XG4gIHByaXZhdGUgYWp2QXZhaWxhYmxlOiBib29sZWFuID0gZmFsc2U7XG4gIHByaXZhdGUgaW5pdGlhbGl6ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGxvZ2dlcjogVmFsaWRhdGlvbkxvZ2dlclNlcnZpY2UpIHtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmUgYWp2IGlzIGluaXRpYWxpemVkIChsYXp5IGluaXRpYWxpemF0aW9uKVxuICAgKi9cbiAgcHJpdmF0ZSBlbnN1cmVJbml0aWFsaXplZCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaW5pdGlhbGl6ZWQpIHtcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZUFqdigpO1xuICAgICAgdGhpcy5pbml0aWFsaXplZCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgYWp2IHZhbGlkYXRvclxuICAgKi9cbiAgcHJpdmF0ZSBpbml0aWFsaXplQWp2KCk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICAvLyBUcnkgdG8gbG9hZCBhanYgLSB1c2UgcmVxdWlyZSBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIEFuZ3VsYXIgYnVpbGQgc3lzdGVtXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cyAgICAgIFxuICAgICAgdGhpcy5hanYgPSBuZXcgQWp2KHtcbiAgICAgICAgYWxsRXJyb3JzOiB0cnVlLFxuICAgICAgICB2ZXJib3NlOiB0cnVlLFxuICAgICAgICBzdHJpY3Q6IGZhbHNlLFxuICAgICAgICB2YWxpZGF0ZVNjaGVtYTogZmFsc2UgLy8gRG9uJ3QgdmFsaWRhdGUgdGhlIHNjaGVtYSBpdHNlbGZcbiAgICAgIH0pO1xuXG4gICAgICAvLyBDb21waWxlIHNjaGVtYSAoY29udmVydCBjb25zdCB0byByZWd1bGFyIG9iamVjdCBmb3IgYWp2KVxuICAgICAgY29uc3Qgc2NoZW1hID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0YWJsZUNvbmZpZ1NjaGVtYSkpO1xuICAgICAgdGhpcy52YWxpZGF0ZUZuID0gdGhpcy5hanYuY29tcGlsZShzY2hlbWEpO1xuICAgICAgdGhpcy5hanZBdmFpbGFibGUgPSB0cnVlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBhanYgaXMgb3B0aW9uYWwgLSBpZiBub3QgaW5zdGFsbGVkLCB2YWxpZGF0aW9uIHdpbGwgdXNlIGN1c3RvbSBydWxlcyBvbmx5XG4gICAgICBjb25zb2xlLndhcm4oJ2FqdiBsaWJyYXJ5IG5vdCBmb3VuZC4gSlNPTiBzY2hlbWEgdmFsaWRhdGlvbiB3aWxsIGJlIGRpc2FibGVkLiBJbnN0YWxsIHdpdGg6IG5wbSBpbnN0YWxsIGFqdicpO1xuICAgICAgdGhpcy5hanZBdmFpbGFibGUgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgSlNPTiBkYXRhIGFnYWluc3QgVGFibGVDb25maWcgc2NoZW1hXG4gICAqIEBwYXJhbSBkYXRhIEpTT04gZGF0YSB0byB2YWxpZGF0ZVxuICAgKiBAcGFyYW0gaW5jbHVkZUN1c3RvbVJ1bGVzIFdoZXRoZXIgdG8gaW5jbHVkZSBjdXN0b20gYnVzaW5lc3MgcnVsZSB2YWxpZGF0aW9uc1xuICAgKiBAcGFyYW0gZW5hYmxlTG9nZ2luZyBXaGV0aGVyIHRvIGxvZyB2YWxpZGF0aW9uIGVycm9ycyAoZGVmYXVsdDogdHJ1ZSlcbiAgICogQHJldHVybnMgVmFsaWRhdGlvbiByZXN1bHRcbiAgICovXG4gIHZhbGlkYXRlKGRhdGE6IGFueSwgaW5jbHVkZUN1c3RvbVJ1bGVzOiBib29sZWFuID0gdHJ1ZSwgZW5hYmxlTG9nZ2luZzogYm9vbGVhbiA9IHRydWUpOiBTY2hlbWFWYWxpZGF0aW9uUmVzdWx0IHtcbiAgICAvLyBFbnN1cmUgYWp2IGlzIGluaXRpYWxpemVkIGJlZm9yZSB2YWxpZGF0aW9uXG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICAgIFxuICAgIGNvbnN0IGFsbEVycm9yczogU2NoZW1hVmFsaWRhdGlvbkVycm9yW10gPSBbXTtcblxuICAgIC8vIDEuIEpTT04gU2NoZW1hIHZhbGlkYXRpb24gKGlmIGFqdiBpcyBhdmFpbGFibGUpXG4gICAgaWYgKHRoaXMuYWp2QXZhaWxhYmxlKSB7XG4gICAgICBjb25zdCBpc1ZhbGlkID0gdGhpcy52YWxpZGF0ZUZuKGRhdGEpO1xuXG4gICAgICBpZiAoIWlzVmFsaWQpIHtcbiAgICAgICAgLy8gQ29udmVydCBhanYgZXJyb3JzIHRvIG91ciBmb3JtYXRcbiAgICAgICAgY29uc3Qgc2NoZW1hRXJyb3JzOiBTY2hlbWFWYWxpZGF0aW9uRXJyb3JbXSA9ICh0aGlzLnZhbGlkYXRlRm4uZXJyb3JzIHx8IFtdKS5tYXAoKGVycm9yOiBhbnkpID0+IHtcbiAgICAgICAgICBjb25zdCBwYXRoID0gZXJyb3IuaW5zdGFuY2VQYXRoIHx8IGVycm9yLnNjaGVtYVBhdGggfHwgJyc7XG4gICAgICAgICAgY29uc3QgZmllbGQgPSB0aGlzLnBhdGhUb0ZpZWxkTmFtZShwYXRoKTtcbiAgICAgICAgICBcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgcGF0aDogcGF0aCxcbiAgICAgICAgICAgIG1lc3NhZ2U6IHRoaXMuZm9ybWF0RXJyb3JNZXNzYWdlKGVycm9yLCBmaWVsZCksXG4gICAgICAgICAgICBjb2RlOiBlcnJvci5rZXl3b3JkIHx8ICdWQUxJREFUSU9OX0VSUk9SJyxcbiAgICAgICAgICAgIHZhbHVlOiBlcnJvci5kYXRhLFxuICAgICAgICAgICAgZmllbGQ6IGZpZWxkXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYWxsRXJyb3JzLnB1c2goLi4uc2NoZW1hRXJyb3JzKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgYWp2IGlzIG5vdCBhdmFpbGFibGUsIGFkZCBhIHdhcm5pbmcgYnV0IGNvbnRpbnVlIHdpdGggY3VzdG9tIHJ1bGVzXG4gICAgICBhbGxFcnJvcnMucHVzaCh7XG4gICAgICAgIHBhdGg6ICcnLFxuICAgICAgICBtZXNzYWdlOiAnSlNPTiBzY2hlbWEgdmFsaWRhdGlvbiBpcyBub3QgYXZhaWxhYmxlLiBQbGVhc2UgaW5zdGFsbCBhanY6IG5wbSBpbnN0YWxsIGFqdicsXG4gICAgICAgIGNvZGU6ICdBSlZfTk9UX0FWQUlMQUJMRScsXG4gICAgICAgIGZpZWxkOiAncm9vdCdcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIDIuIEN1c3RvbSBidXNpbmVzcyBydWxlIHZhbGlkYXRpb25cbiAgICBpZiAoaW5jbHVkZUN1c3RvbVJ1bGVzICYmIGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09ICdvYmplY3QnKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBjdXN0b21FcnJvcnMgPSB2YWxpZGF0ZUN1c3RvbVJ1bGVzKGRhdGEgYXMgYW55KTtcbiAgICAgICAgYWxsRXJyb3JzLnB1c2goLi4uY3VzdG9tRXJyb3JzKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgYWxsRXJyb3JzLnB1c2goe1xuICAgICAgICAgIHBhdGg6ICcnLFxuICAgICAgICAgIG1lc3NhZ2U6IGBDdXN0b20gdmFsaWRhdGlvbiBmYWlsZWQ6ICR7ZXJyb3IubWVzc2FnZX1gLFxuICAgICAgICAgIGNvZGU6ICdDVVNUT01fVkFMSURBVElPTl9FUlJPUicsXG4gICAgICAgICAgZmllbGQ6ICdyb290J1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSB7XG4gICAgICB2YWxpZDogYWxsRXJyb3JzLmxlbmd0aCA9PT0gMCxcbiAgICAgIGVycm9yczogYWxsRXJyb3JzLFxuICAgICAgYWp2QXZhaWxhYmxlOiB0aGlzLmFqdkF2YWlsYWJsZVxuICAgIH07XG5cbiAgICAvLyBMb2cgdmFsaWRhdGlvbiBlcnJvcnMgaWYgdmFsaWRhdGlvbiBmYWlsZWQgYW5kIGxvZ2dpbmcgaXMgZW5hYmxlZFxuICAgIGlmICghcmVzdWx0LnZhbGlkICYmIGVuYWJsZUxvZ2dpbmcpIHtcbiAgICAgIHRoaXMubG9nZ2VyLmxvZ1ZhbGlkYXRpb25FcnJvcnMoYWxsRXJyb3JzLCAnc2NoZW1hLXZhbGlkYXRpb24nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIEpTT04gc3RyaW5nXG4gICAqIEBwYXJhbSBqc29uU3RyaW5nIEpTT04gc3RyaW5nIHRvIHZhbGlkYXRlXG4gICAqIEBwYXJhbSBpbmNsdWRlQ3VzdG9tUnVsZXMgV2hldGhlciB0byBpbmNsdWRlIGN1c3RvbSBidXNpbmVzcyBydWxlIHZhbGlkYXRpb25zXG4gICAqIEBwYXJhbSBlbmFibGVMb2dnaW5nIFdoZXRoZXIgdG8gbG9nIHZhbGlkYXRpb24gZXJyb3JzIChkZWZhdWx0OiB0cnVlKVxuICAgKiBAcmV0dXJucyBWYWxpZGF0aW9uIHJlc3VsdFxuICAgKi9cbiAgdmFsaWRhdGVKU09OU3RyaW5nKGpzb25TdHJpbmc6IHN0cmluZywgaW5jbHVkZUN1c3RvbVJ1bGVzOiBib29sZWFuID0gdHJ1ZSwgZW5hYmxlTG9nZ2luZzogYm9vbGVhbiA9IHRydWUpOiBTY2hlbWFWYWxpZGF0aW9uUmVzdWx0IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgZGF0YSA9IEpTT04ucGFyc2UoanNvblN0cmluZyk7XG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZShkYXRhLCBpbmNsdWRlQ3VzdG9tUnVsZXMsIGVuYWJsZUxvZ2dpbmcpO1xuICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IHtcbiAgICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgICBlcnJvcnM6IFt7XG4gICAgICAgICAgcGF0aDogJycsXG4gICAgICAgICAgbWVzc2FnZTogYEludmFsaWQgSlNPTjogJHtlcnJvci5tZXNzYWdlfWAsXG4gICAgICAgICAgY29kZTogJ0pTT05fUEFSU0VfRVJST1InLFxuICAgICAgICAgIHZhbHVlOiBqc29uU3RyaW5nLFxuICAgICAgICAgIGZpZWxkOiAncm9vdCdcbiAgICAgICAgfV0sXG4gICAgICAgIGFqdkF2YWlsYWJsZTogdGhpcy5hanZBdmFpbGFibGVcbiAgICAgIH07XG5cbiAgICAgIC8vIExvZyBKU09OIHBhcnNlIGVycm9ycyBpZiBsb2dnaW5nIGlzIGVuYWJsZWRcbiAgICAgIGlmIChlbmFibGVMb2dnaW5nKSB7XG4gICAgICAgIHRoaXMubG9nZ2VyLmxvZ1ZhbGlkYXRpb25FcnJvcnMocmVzdWx0LmVycm9ycywgJ3NjaGVtYS12YWxpZGF0aW9uJywge1xuICAgICAgICAgIGNvbmZpZ1NuaXBwZXQ6IGpzb25TdHJpbmcuc3Vic3RyaW5nKDAsIDIwMCkgLy8gSW5jbHVkZSBmaXJzdCAyMDAgY2hhcnMgYXMgY29udGV4dFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgYWp2IGlzIGF2YWlsYWJsZVxuICAgKi9cbiAgaXNBdmFpbGFibGUoKTogYm9vbGVhbiB7XG4gICAgdGhpcy5lbnN1cmVJbml0aWFsaXplZCgpO1xuICAgIHJldHVybiB0aGlzLmFqdkF2YWlsYWJsZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0IEpTT04gcGF0aCB0byB1c2VyLWZyaWVuZGx5IGZpZWxkIG5hbWVcbiAgICovXG4gIHByaXZhdGUgcGF0aFRvRmllbGROYW1lKHBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCFwYXRoKSByZXR1cm4gJ3Jvb3QnO1xuICAgIFxuICAgIC8vIFJlbW92ZSBsZWFkaW5nIHNsYXNoXG4gICAgbGV0IGZpZWxkID0gcGF0aC5yZXBsYWNlKC9eXFwvLywgJycpO1xuICAgIFxuICAgIC8vIFJlcGxhY2UgYXJyYXkgaW5kaWNlcyB3aXRoIGJyYWNrZXRzXG4gICAgZmllbGQgPSBmaWVsZC5yZXBsYWNlKC9cXC8oXFxkKykvZywgJ1skMV0nKTtcbiAgICBcbiAgICAvLyBSZXBsYWNlIHNsYXNoZXMgd2l0aCBkb3RzXG4gICAgZmllbGQgPSBmaWVsZC5yZXBsYWNlKC9cXC8vZywgJy4nKTtcbiAgICBcbiAgICByZXR1cm4gZmllbGQgfHwgJ3Jvb3QnO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcm1hdCBlcnJvciBtZXNzYWdlIGZyb20gYWp2IGVycm9yXG4gICAqL1xuICBwcml2YXRlIGZvcm1hdEVycm9yTWVzc2FnZShlcnJvcjogYW55LCBmaWVsZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBrZXl3b3JkID0gZXJyb3Iua2V5d29yZDtcbiAgICBjb25zdCBwYXJhbXMgPSBlcnJvci5wYXJhbXMgfHwge307XG4gICAgXG4gICAgc3dpdGNoIChrZXl3b3JkKSB7XG4gICAgICBjYXNlICdyZXF1aXJlZCc6XG4gICAgICAgIHJldHVybiBgRmllbGQgJyR7ZmllbGR9JyBpcyByZXF1aXJlZCBidXQgbWlzc2luZ2A7XG4gICAgICBcbiAgICAgIGNhc2UgJ3R5cGUnOlxuICAgICAgICByZXR1cm4gYEZpZWxkICcke2ZpZWxkfScgbXVzdCBiZSBvZiB0eXBlICR7cGFyYW1zLnR5cGV9LCBidXQgZ290ICR7dHlwZW9mIGVycm9yLmRhdGF9YDtcbiAgICAgIFxuICAgICAgY2FzZSAnZW51bSc6XG4gICAgICAgIHJldHVybiBgRmllbGQgJyR7ZmllbGR9JyBtdXN0IGJlIG9uZSBvZjogJHtwYXJhbXMuYWxsb3dlZFZhbHVlcz8uam9pbignLCAnKSB8fCAnYWxsb3dlZCB2YWx1ZXMnfWA7XG4gICAgICBcbiAgICAgIGNhc2UgJ3BhdHRlcm4nOlxuICAgICAgICByZXR1cm4gYEZpZWxkICcke2ZpZWxkfScgZG9lcyBub3QgbWF0Y2ggcmVxdWlyZWQgcGF0dGVybjogJHtwYXJhbXMucGF0dGVybn1gO1xuICAgICAgXG4gICAgICBjYXNlICdtaW5pbXVtJzpcbiAgICAgICAgcmV0dXJuIGBGaWVsZCAnJHtmaWVsZH0nIG11c3QgYmUgYXQgbGVhc3QgJHtwYXJhbXMubGltaXR9YDtcbiAgICAgIFxuICAgICAgY2FzZSAnbWF4aW11bSc6XG4gICAgICAgIHJldHVybiBgRmllbGQgJyR7ZmllbGR9JyBtdXN0IGJlIGF0IG1vc3QgJHtwYXJhbXMubGltaXR9YDtcbiAgICAgIFxuICAgICAgY2FzZSAnbWluTGVuZ3RoJzpcbiAgICAgICAgcmV0dXJuIGBGaWVsZCAnJHtmaWVsZH0nIG11c3QgaGF2ZSBhdCBsZWFzdCAke3BhcmFtcy5saW1pdH0gaXRlbXNgO1xuICAgICAgXG4gICAgICBjYXNlICdtYXhMZW5ndGgnOlxuICAgICAgICByZXR1cm4gYEZpZWxkICcke2ZpZWxkfScgbXVzdCBoYXZlIGF0IG1vc3QgJHtwYXJhbXMubGltaXR9IGl0ZW1zYDtcbiAgICAgIFxuICAgICAgY2FzZSAnbWluSXRlbXMnOlxuICAgICAgICByZXR1cm4gYEFycmF5ICcke2ZpZWxkfScgbXVzdCBoYXZlIGF0IGxlYXN0ICR7cGFyYW1zLmxpbWl0fSBpdGVtc2A7XG4gICAgICBcbiAgICAgIGNhc2UgJ21heEl0ZW1zJzpcbiAgICAgICAgcmV0dXJuIGBBcnJheSAnJHtmaWVsZH0nIG11c3QgaGF2ZSBhdCBtb3N0ICR7cGFyYW1zLmxpbWl0fSBpdGVtc2A7XG4gICAgICBcbiAgICAgIGNhc2UgJ2FkZGl0aW9uYWxQcm9wZXJ0aWVzJzpcbiAgICAgICAgcmV0dXJuIGBGaWVsZCAnJHtmaWVsZH0nIGNvbnRhaW5zIHVua25vd24gcHJvcGVydHk6ICR7cGFyYW1zLmFkZGl0aW9uYWxQcm9wZXJ0eX1gO1xuICAgICAgXG4gICAgICBjYXNlICdvbmVPZic6XG4gICAgICAgIHJldHVybiBgRmllbGQgJyR7ZmllbGR9JyBkb2VzIG5vdCBtYXRjaCBhbnkgb2YgdGhlIGFsbG93ZWQgdHlwZXNgO1xuICAgICAgXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gZXJyb3IubWVzc2FnZSB8fCBgRmllbGQgJyR7ZmllbGR9JyBpcyBpbnZhbGlkYDtcbiAgICB9XG4gIH1cbn1cblxuIl19
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { Injectable } from '@angular/core';
|
|
2
|
-
import * as i0 from "@angular/core";
|
|
3
|
-
export class RowValidationService {
|
|
4
|
-
/**
|
|
5
|
-
* Validate a single row
|
|
6
|
-
*/
|
|
7
|
-
validateRow(rowData, cells, rowIndex, validator) {
|
|
8
|
-
try {
|
|
9
|
-
return validator.validateRow(rowData, cells, rowIndex);
|
|
10
|
-
}
|
|
11
|
-
catch (error) {
|
|
12
|
-
return {
|
|
13
|
-
valid: false,
|
|
14
|
-
error: `Validation error: ${error.message}`,
|
|
15
|
-
errors: [error.message]
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Validate entire table
|
|
21
|
-
*/
|
|
22
|
-
validateTable(rows, config, validator, rowValidationResults) {
|
|
23
|
-
try {
|
|
24
|
-
return validator.validateTable(rows, config, rowValidationResults);
|
|
25
|
-
}
|
|
26
|
-
catch (error) {
|
|
27
|
-
return {
|
|
28
|
-
valid: false,
|
|
29
|
-
globalErrors: [`Table validation error: ${error.message}`]
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
RowValidationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: RowValidationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
35
|
-
RowValidationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: RowValidationService, providedIn: 'root' });
|
|
36
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: RowValidationService, decorators: [{
|
|
37
|
-
type: Injectable,
|
|
38
|
-
args: [{
|
|
39
|
-
providedIn: 'root'
|
|
40
|
-
}]
|
|
41
|
-
}] });
|
|
42
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm93LXZhbGlkYXRpb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NtYXJ0LXRhYmxlL3NyYy9saWIvc2VydmljZXMvcm93LXZhbGlkYXRpb24uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQVMzQyxNQUFNLE9BQU8sb0JBQW9CO0lBQy9COztPQUVHO0lBQ0gsV0FBVyxDQUNULE9BQVksRUFDWixLQUFhLEVBQ2IsUUFBZ0IsRUFDaEIsU0FBdUI7UUFFdkIsSUFBSTtZQUNGLE9BQU8sU0FBUyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1NBQ3hEO1FBQUMsT0FBTyxLQUFVLEVBQUU7WUFDbkIsT0FBTztnQkFDTCxLQUFLLEVBQUUsS0FBSztnQkFDWixLQUFLLEVBQUUscUJBQXFCLEtBQUssQ0FBQyxPQUFPLEVBQUU7Z0JBQzNDLE1BQU0sRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7YUFDeEIsQ0FBQztTQUNIO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsYUFBYSxDQUNYLElBQVcsRUFDWCxNQUFtQixFQUNuQixTQUF5QixFQUN6QixvQkFBdUQ7UUFFdkQsSUFBSTtZQUNGLE9BQU8sU0FBUyxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLG9CQUFvQixDQUFDLENBQUM7U0FDcEU7UUFBQyxPQUFPLEtBQVUsRUFBRTtZQUNuQixPQUFPO2dCQUNMLEtBQUssRUFBRSxLQUFLO2dCQUNaLFlBQVksRUFBRSxDQUFDLDJCQUEyQixLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7YUFDM0QsQ0FBQztTQUNIO0lBQ0gsQ0FBQzs7aUhBdENVLG9CQUFvQjtxSEFBcEIsb0JBQW9CLGNBRm5CLE1BQU07MkZBRVAsb0JBQW9CO2tCQUhoQyxVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENlbGwgfSBmcm9tICcuLi9yZW5kZXJlci9tb2RlbHMvY2VsbC5jbGFzcyc7XG5pbXBvcnQgeyBSb3dWYWxpZGF0b3IsIFJvd1ZhbGlkYXRpb25SZXN1bHQgfSBmcm9tICcuLi9tb2RlbHMvcm93LXZhbGlkYXRvci5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgVGFibGVWYWxpZGF0b3IsIFRhYmxlVmFsaWRhdGlvblJlc3VsdCB9IGZyb20gJy4uL21vZGVscy90YWJsZS12YWxpZGF0b3IuaW50ZXJmYWNlJztcbmltcG9ydCB7IFRhYmxlQ29uZmlnIH0gZnJvbSAnLi4vbW9kZWxzL3RhYmxlLWNvbmZpZy5pbnRlcmZhY2UnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBSb3dWYWxpZGF0aW9uU2VydmljZSB7XG4gIC8qKlxuICAgKiBWYWxpZGF0ZSBhIHNpbmdsZSByb3dcbiAgICovXG4gIHZhbGlkYXRlUm93KFxuICAgIHJvd0RhdGE6IGFueSxcbiAgICBjZWxsczogQ2VsbFtdLFxuICAgIHJvd0luZGV4OiBudW1iZXIsXG4gICAgdmFsaWRhdG9yOiBSb3dWYWxpZGF0b3JcbiAgKTogUm93VmFsaWRhdGlvblJlc3VsdCB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB2YWxpZGF0b3IudmFsaWRhdGVSb3cocm93RGF0YSwgY2VsbHMsIHJvd0luZGV4KTtcbiAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB2YWxpZDogZmFsc2UsXG4gICAgICAgIGVycm9yOiBgVmFsaWRhdGlvbiBlcnJvcjogJHtlcnJvci5tZXNzYWdlfWAsXG4gICAgICAgIGVycm9yczogW2Vycm9yLm1lc3NhZ2VdXG4gICAgICB9O1xuICAgIH1cbiAgfVxuICBcbiAgLyoqXG4gICAqIFZhbGlkYXRlIGVudGlyZSB0YWJsZVxuICAgKi9cbiAgdmFsaWRhdGVUYWJsZShcbiAgICByb3dzOiBhbnlbXSxcbiAgICBjb25maWc6IFRhYmxlQ29uZmlnLFxuICAgIHZhbGlkYXRvcjogVGFibGVWYWxpZGF0b3IsXG4gICAgcm93VmFsaWRhdGlvblJlc3VsdHM/OiBNYXA8bnVtYmVyLCBSb3dWYWxpZGF0aW9uUmVzdWx0PlxuICApOiBUYWJsZVZhbGlkYXRpb25SZXN1bHQge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gdmFsaWRhdG9yLnZhbGlkYXRlVGFibGUocm93cywgY29uZmlnLCByb3dWYWxpZGF0aW9uUmVzdWx0cyk7XG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdmFsaWQ6IGZhbHNlLFxuICAgICAgICBnbG9iYWxFcnJvcnM6IFtgVGFibGUgdmFsaWRhdGlvbiBlcnJvcjogJHtlcnJvci5tZXNzYWdlfWBdXG4gICAgICB9O1xuICAgIH1cbiAgfVxufVxuXG4iXX0=
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validation Logger Service
|
|
3
|
-
* Automatically logs validation errors and provides functionality to download them as a log file
|
|
4
|
-
*/
|
|
5
|
-
import { Injectable } from '@angular/core';
|
|
6
|
-
import * as i0 from "@angular/core";
|
|
7
|
-
export class ValidationLoggerService {
|
|
8
|
-
constructor() {
|
|
9
|
-
this.logEntries = [];
|
|
10
|
-
this.downloadTimeoutId = null;
|
|
11
|
-
this.DOWNLOAD_DELAY_MS = 500; // Wait 500ms after last error before downloading
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Log validation errors
|
|
15
|
-
* @param errors Array of validation errors
|
|
16
|
-
* @param source Source of validation (e.g., 'import', 'renderer', 'schema-validation')
|
|
17
|
-
* @param context Optional context information
|
|
18
|
-
* @param autoDownload Whether to automatically download log file (default: true)
|
|
19
|
-
*/
|
|
20
|
-
logValidationErrors(errors, source, context, autoDownload = true) {
|
|
21
|
-
if (errors.length === 0) {
|
|
22
|
-
return; // Don't log if there are no errors
|
|
23
|
-
}
|
|
24
|
-
const entry = {
|
|
25
|
-
timestamp: new Date().toISOString(),
|
|
26
|
-
source: source,
|
|
27
|
-
errors: errors,
|
|
28
|
-
context: context
|
|
29
|
-
};
|
|
30
|
-
this.logEntries.push(entry);
|
|
31
|
-
// Schedule automatic download after errors accumulate (debounced)
|
|
32
|
-
if (autoDownload) {
|
|
33
|
-
this.scheduleDownload();
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Schedule log file download with debounce
|
|
38
|
-
* This ensures we only download once after all errors are accumulated
|
|
39
|
-
*/
|
|
40
|
-
scheduleDownload() {
|
|
41
|
-
// Clear any existing timeout
|
|
42
|
-
if (this.downloadTimeoutId !== null) {
|
|
43
|
-
clearTimeout(this.downloadTimeoutId);
|
|
44
|
-
}
|
|
45
|
-
// Schedule download after delay
|
|
46
|
-
// If more errors come in before timeout fires, this will be cancelled and rescheduled
|
|
47
|
-
this.downloadTimeoutId = setTimeout(() => {
|
|
48
|
-
this.downloadLogFileOnError();
|
|
49
|
-
this.downloadTimeoutId = null;
|
|
50
|
-
}, this.DOWNLOAD_DELAY_MS);
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Download log file with timestamped filename
|
|
54
|
-
* Called automatically when validation errors occur (after debounce delay)
|
|
55
|
-
*/
|
|
56
|
-
downloadLogFileOnError() {
|
|
57
|
-
// Generate filename with timestamp to avoid overwriting
|
|
58
|
-
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, -5); // Format: 2024-01-15T10-30-45
|
|
59
|
-
const filename = `smart-table-validation-errors-${timestamp}.log`;
|
|
60
|
-
this.downloadLogFile(filename);
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Get all log entries
|
|
64
|
-
* @returns Array of all log entries
|
|
65
|
-
*/
|
|
66
|
-
getLogEntries() {
|
|
67
|
-
return [...this.logEntries];
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Format all log entries as plain text
|
|
71
|
-
* @returns Formatted log text
|
|
72
|
-
*/
|
|
73
|
-
formatLogAsText() {
|
|
74
|
-
if (this.logEntries.length === 0) {
|
|
75
|
-
return 'No validation errors logged.\n';
|
|
76
|
-
}
|
|
77
|
-
let logText = `Smart Table Validation Error Log\n`;
|
|
78
|
-
logText += `Generated: ${new Date().toISOString()}\n`;
|
|
79
|
-
logText += `Total Validation Failures: ${this.logEntries.length}\n`;
|
|
80
|
-
logText += `${'='.repeat(80)}\n\n`;
|
|
81
|
-
this.logEntries.forEach((entry, index) => {
|
|
82
|
-
logText += this.formatLogEntry(entry, index + 1);
|
|
83
|
-
logText += '\n';
|
|
84
|
-
});
|
|
85
|
-
return logText;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Format a single log entry as plain text
|
|
89
|
-
* @param entry Log entry to format
|
|
90
|
-
* @param entryNumber Entry number (for display)
|
|
91
|
-
* @returns Formatted entry text
|
|
92
|
-
*/
|
|
93
|
-
formatLogEntry(entry, entryNumber) {
|
|
94
|
-
let text = `[${entry.timestamp}] Validation Failed - Source: ${entry.source}\n`;
|
|
95
|
-
// Add context information if available
|
|
96
|
-
if (entry.context) {
|
|
97
|
-
if (entry.context.fileName) {
|
|
98
|
-
text += `File: ${entry.context.fileName}\n`;
|
|
99
|
-
}
|
|
100
|
-
if (entry.context.storageKey) {
|
|
101
|
-
text += `Storage Key: ${entry.context.storageKey}\n`;
|
|
102
|
-
}
|
|
103
|
-
if (entry.context.configSnippet) {
|
|
104
|
-
text += `Config Snippet: ${entry.context.configSnippet}\n`;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
text += `${'━'.repeat(80)}\n`;
|
|
108
|
-
// Format each error
|
|
109
|
-
entry.errors.forEach((error, errorIndex) => {
|
|
110
|
-
text += `Error ${errorIndex + 1}:\n`;
|
|
111
|
-
if (error.field) {
|
|
112
|
-
text += ` Field: ${error.field}\n`;
|
|
113
|
-
}
|
|
114
|
-
if (error.path) {
|
|
115
|
-
text += ` Path: ${error.path}\n`;
|
|
116
|
-
}
|
|
117
|
-
if (error.code) {
|
|
118
|
-
text += ` Code: ${error.code}\n`;
|
|
119
|
-
}
|
|
120
|
-
if (error.message) {
|
|
121
|
-
text += ` Message: ${error.message}\n`;
|
|
122
|
-
}
|
|
123
|
-
if (error.value !== undefined && error.value !== null) {
|
|
124
|
-
const valueStr = typeof error.value === 'object'
|
|
125
|
-
? JSON.stringify(error.value, null, 2).split('\n').map(line => ` ${line}`).join('\n')
|
|
126
|
-
: String(error.value);
|
|
127
|
-
text += ` Value: ${valueStr}\n`;
|
|
128
|
-
}
|
|
129
|
-
text += '\n';
|
|
130
|
-
});
|
|
131
|
-
text += `${'━'.repeat(80)}\n`;
|
|
132
|
-
return text;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Download log file
|
|
136
|
-
* @param filename Optional filename (default: 'smart-table-validation-errors.log')
|
|
137
|
-
*/
|
|
138
|
-
downloadLogFile(filename = 'smart-table-validation-errors.log') {
|
|
139
|
-
const logText = this.formatLogAsText();
|
|
140
|
-
const blob = new Blob([logText], { type: 'text/plain' });
|
|
141
|
-
const url = URL.createObjectURL(blob);
|
|
142
|
-
const link = document.createElement('a');
|
|
143
|
-
link.href = url;
|
|
144
|
-
link.download = filename;
|
|
145
|
-
document.body.appendChild(link);
|
|
146
|
-
link.click();
|
|
147
|
-
document.body.removeChild(link);
|
|
148
|
-
URL.revokeObjectURL(url);
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Clear all log entries
|
|
152
|
-
*/
|
|
153
|
-
clearLog() {
|
|
154
|
-
// Cancel any pending download
|
|
155
|
-
if (this.downloadTimeoutId !== null) {
|
|
156
|
-
clearTimeout(this.downloadTimeoutId);
|
|
157
|
-
this.downloadTimeoutId = null;
|
|
158
|
-
}
|
|
159
|
-
this.logEntries = [];
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Get number of log entries
|
|
163
|
-
* @returns Number of log entries
|
|
164
|
-
*/
|
|
165
|
-
getLogSize() {
|
|
166
|
-
return this.logEntries.length;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
ValidationLoggerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ValidationLoggerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
170
|
-
ValidationLoggerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ValidationLoggerService, providedIn: 'root' });
|
|
171
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: ValidationLoggerService, decorators: [{
|
|
172
|
-
type: Injectable,
|
|
173
|
-
args: [{
|
|
174
|
-
providedIn: 'root'
|
|
175
|
-
}]
|
|
176
|
-
}] });
|
|
177
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi1sb2dnZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NtYXJ0LXRhYmxlL3NyYy9saWIvc2VydmljZXMvdmFsaWRhdGlvbi1sb2dnZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQW1DM0MsTUFBTSxPQUFPLHVCQUF1QjtJQUhwQztRQUlVLGVBQVUsR0FBeUIsRUFBRSxDQUFDO1FBQ3RDLHNCQUFpQixHQUFRLElBQUksQ0FBQztRQUNyQixzQkFBaUIsR0FBRyxHQUFHLENBQUMsQ0FBQyxpREFBaUQ7S0FnTTVGO0lBOUxDOzs7Ozs7T0FNRztJQUNILG1CQUFtQixDQUNqQixNQUErQixFQUMvQixNQUFjLEVBQ2QsT0FJQyxFQUNELGVBQXdCLElBQUk7UUFFNUIsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtZQUN2QixPQUFPLENBQUMsbUNBQW1DO1NBQzVDO1FBRUQsTUFBTSxLQUFLLEdBQXVCO1lBQ2hDLFNBQVMsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRTtZQUNuQyxNQUFNLEVBQUUsTUFBTTtZQUNkLE1BQU0sRUFBRSxNQUFNO1lBQ2QsT0FBTyxFQUFFLE9BQU87U0FDakIsQ0FBQztRQUVGLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRTVCLGtFQUFrRTtRQUNsRSxJQUFJLFlBQVksRUFBRTtZQUNoQixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztTQUN6QjtJQUNILENBQUM7SUFFRDs7O09BR0c7SUFDSyxnQkFBZ0I7UUFDdEIsNkJBQTZCO1FBQzdCLElBQUksSUFBSSxDQUFDLGlCQUFpQixLQUFLLElBQUksRUFBRTtZQUNuQyxZQUFZLENBQUMsSUFBSSxDQUFDLGlCQUFp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IFNlcnZpY2VcbiAqIEF1dG9tYXRpY2FsbHkgbG9ncyB2YWxpZGF0aW9uIGVycm9ycyBhbmQgcHJvdmlkZXMgZnVuY3Rpb25hbGl0eSB0byBkb3dubG9hZCB0aGVtIGFzIGEgbG9nIGZpbGVcbiAqL1xuXG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTY2hlbWFWYWxpZGF0aW9uRXJyb3IgfSBmcm9tICcuLi9tb2RlbHMvc2NoZW1hLXZhbGlkYXRpb24uaW50ZXJmYWNlJztcblxuLyoqXG4gKiBWYWxpZGF0aW9uIGxvZyBlbnRyeSBpbnRlcmZhY2VcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0aW9uTG9nRW50cnkge1xuICAvKipcbiAgICogSVNPIHRpbWVzdGFtcCB3aGVuIHZhbGlkYXRpb24gZmFpbGVkXG4gICAqL1xuICB0aW1lc3RhbXA6IHN0cmluZztcblxuICAvKipcbiAgICogU291cmNlIG9mIHZhbGlkYXRpb24gKGUuZy4sICdpbXBvcnQnLCAncmVuZGVyZXInLCAnc2NoZW1hLXZhbGlkYXRpb24nKVxuICAgKi9cbiAgc291cmNlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEFycmF5IG9mIHZhbGlkYXRpb24gZXJyb3JzXG4gICAqL1xuICBlcnJvcnM6IFNjaGVtYVZhbGlkYXRpb25FcnJvcltdO1xuXG4gIC8qKlxuICAgKiBPcHRpb25hbCBjb250ZXh0IGluZm9ybWF0aW9uXG4gICAqL1xuICBjb250ZXh0Pzoge1xuICAgIGZpbGVOYW1lPzogc3RyaW5nO1xuICAgIGNvbmZpZ1NuaXBwZXQ/OiBzdHJpbmc7XG4gICAgc3RvcmFnZUtleT86IHN0cmluZztcbiAgfTtcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgVmFsaWRhdGlvbkxvZ2dlclNlcnZpY2Uge1xuICBwcml2YXRlIGxvZ0VudHJpZXM6IFZhbGlkYXRpb25Mb2dFbnRyeVtdID0gW107XG4gIHByaXZhdGUgZG93bmxvYWRUaW1lb3V0SWQ6IGFueSA9IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkgRE9XTkxPQURfREVMQVlfTVMgPSA1MDA7IC8vIFdhaXQgNTAwbXMgYWZ0ZXIgbGFzdCBlcnJvciBiZWZvcmUgZG93bmxvYWRpbmdcblxuICAvKipcbiAgICogTG9nIHZhbGlkYXRpb24gZXJyb3JzXG4gICAqIEBwYXJhbSBlcnJvcnMgQXJyYXkgb2YgdmFsaWRhdGlvbiBlcnJvcnNcbiAgICogQHBhcmFtIHNvdXJjZSBTb3VyY2Ugb2YgdmFsaWRhdGlvbiAoZS5nLiwgJ2ltcG9ydCcsICdyZW5kZXJlcicsICdzY2hlbWEtdmFsaWRhdGlvbicpXG4gICAqIEBwYXJhbSBjb250ZXh0IE9wdGlvbmFsIGNvbnRleHQgaW5mb3JtYXRpb25cbiAgICogQHBhcmFtIGF1dG9Eb3dubG9hZCBXaGV0aGVyIHRvIGF1dG9tYXRpY2FsbHkgZG93bmxvYWQgbG9nIGZpbGUgKGRlZmF1bHQ6IHRydWUpXG4gICAqL1xuICBsb2dWYWxpZGF0aW9uRXJyb3JzKFxuICAgIGVycm9yczogU2NoZW1hVmFsaWRhdGlvbkVycm9yW10sXG4gICAgc291cmNlOiBzdHJpbmcsXG4gICAgY29udGV4dD86IHtcbiAgICAgIGZpbGVOYW1lPzogc3RyaW5nO1xuICAgICAgY29uZmlnU25pcHBldD86IHN0cmluZztcbiAgICAgIHN0b3JhZ2VLZXk/OiBzdHJpbmc7XG4gICAgfSxcbiAgICBhdXRvRG93bmxvYWQ6IGJvb2xlYW4gPSB0cnVlXG4gICk6IHZvaWQge1xuICAgIGlmIChlcnJvcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47IC8vIERvbid0IGxvZyBpZiB0aGVyZSBhcmUgbm8gZXJyb3JzXG4gICAgfVxuXG4gICAgY29uc3QgZW50cnk6IFZhbGlkYXRpb25Mb2dFbnRyeSA9IHtcbiAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgICAgc291cmNlOiBzb3VyY2UsXG4gICAgICBlcnJvcnM6IGVycm9ycyxcbiAgICAgIGNvbnRleHQ6IGNvbnRleHRcbiAgICB9O1xuXG4gICAgdGhpcy5sb2dFbnRyaWVzLnB1c2goZW50cnkpO1xuXG4gICAgLy8gU2NoZWR1bGUgYXV0b21hdGljIGRvd25sb2FkIGFmdGVyIGVycm9ycyBhY2N1bXVsYXRlIChkZWJvdW5jZWQpXG4gICAgaWYgKGF1dG9Eb3dubG9hZCkge1xuICAgICAgdGhpcy5zY2hlZHVsZURvd25sb2FkKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNjaGVkdWxlIGxvZyBmaWxlIGRvd25sb2FkIHdpdGggZGVib3VuY2VcbiAgICogVGhpcyBlbnN1cmVzIHdlIG9ubHkgZG93bmxvYWQgb25jZSBhZnRlciBhbGwgZXJyb3JzIGFyZSBhY2N1bXVsYXRlZFxuICAgKi9cbiAgcHJpdmF0ZSBzY2hlZHVsZURvd25sb2FkKCk6IHZvaWQge1xuICAgIC8vIENsZWFyIGFueSBleGlzdGluZyB0aW1lb3V0XG4gICAgaWYgKHRoaXMuZG93bmxvYWRUaW1lb3V0SWQgIT09IG51bGwpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLmRvd25sb2FkVGltZW91dElkKTtcbiAgICB9XG5cbiAgICAvLyBTY2hlZHVsZSBkb3dubG9hZCBhZnRlciBkZWxheVxuICAgIC8vIElmIG1vcmUgZXJyb3JzIGNvbWUgaW4gYmVmb3JlIHRpbWVvdXQgZmlyZXMsIHRoaXMgd2lsbCBiZSBjYW5jZWxsZWQgYW5kIHJlc2NoZWR1bGVkXG4gICAgdGhpcy5kb3dubG9hZFRpbWVvdXRJZCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5kb3dubG9hZExvZ0ZpbGVPbkVycm9yKCk7XG4gICAgICB0aGlzLmRvd25sb2FkVGltZW91dElkID0gbnVsbDtcbiAgICB9LCB0aGlzLkRPV05MT0FEX0RFTEFZX01TKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEb3dubG9hZCBsb2cgZmlsZSB3aXRoIHRpbWVzdGFtcGVkIGZpbGVuYW1lXG4gICAqIENhbGxlZCBhdXRvbWF0aWNhbGx5IHdoZW4gdmFsaWRhdGlvbiBlcnJvcnMgb2NjdXIgKGFmdGVyIGRlYm91bmNlIGRlbGF5KVxuICAgKi9cbiAgcHJpdmF0ZSBkb3dubG9hZExvZ0ZpbGVPbkVycm9yKCk6IHZvaWQge1xuICAgIC8vIEdlbmVyYXRlIGZpbGVuYW1lIHdpdGggdGltZXN0YW1wIHRvIGF2b2lkIG92ZXJ3cml0aW5nXG4gICAgY29uc3QgdGltZXN0YW1wID0gbmV3IERhdGUoKS50b0lTT1N0cmluZygpLnJlcGxhY2UoL1s6Ll0vZywgJy0nKS5zbGljZSgwLCAtNSk7IC8vIEZvcm1hdDogMjAyNC0wMS0xNVQxMC0zMC00NVxuICAgIGNvbnN0IGZpbGVuYW1lID0gYHNtYXJ0LXRhYmxlLXZhbGlkYXRpb24tZXJyb3JzLSR7dGltZXN0YW1wfS5sb2dgO1xuICAgIHRoaXMuZG93bmxvYWRMb2dGaWxlKGZpbGVuYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWxsIGxvZyBlbnRyaWVzXG4gICAqIEByZXR1cm5zIEFycmF5IG9mIGFsbCBsb2cgZW50cmllc1xuICAgKi9cbiAgZ2V0TG9nRW50cmllcygpOiBWYWxpZGF0aW9uTG9nRW50cnlbXSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLmxvZ0VudHJpZXNdO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcm1hdCBhbGwgbG9nIGVudHJpZXMgYXMgcGxhaW4gdGV4dFxuICAgKiBAcmV0dXJucyBGb3JtYXR0ZWQgbG9nIHRleHRcbiAgICovXG4gIGZvcm1hdExvZ0FzVGV4dCgpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLmxvZ0VudHJpZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gJ05vIHZhbGlkYXRpb24gZXJyb3JzIGxvZ2dlZC5cXG4nO1xuICAgIH1cblxuICAgIGxldCBsb2dUZXh0ID0gYFNtYXJ0IFRhYmxlIFZhbGlkYXRpb24gRXJyb3IgTG9nXFxuYDtcbiAgICBsb2dUZXh0ICs9IGBHZW5lcmF0ZWQ6ICR7bmV3IERhdGUoKS50b0lTT1N0cmluZygpfVxcbmA7XG4gICAgbG9nVGV4dCArPSBgVG90YWwgVmFsaWRhdGlvbiBGYWlsdXJlczogJHt0aGlzLmxvZ0VudHJpZXMubGVuZ3RofVxcbmA7XG4gICAgbG9nVGV4dCArPSBgJHsnPScucmVwZWF0KDgwKX1cXG5cXG5gO1xuXG4gICAgdGhpcy5sb2dFbnRyaWVzLmZvckVhY2goKGVudHJ5LCBpbmRleCkgPT4ge1xuICAgICAgbG9nVGV4dCArPSB0aGlzLmZvcm1hdExvZ0VudHJ5KGVudHJ5LCBpbmRleCArIDEpO1xuICAgICAgbG9nVGV4dCArPSAnXFxuJztcbiAgICB9KTtcblxuICAgIHJldHVybiBsb2dUZXh0O1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcm1hdCBhIHNpbmdsZSBsb2cgZW50cnkgYXMgcGxhaW4gdGV4dFxuICAgKiBAcGFyYW0gZW50cnkgTG9nIGVudHJ5IHRvIGZvcm1hdFxuICAgKiBAcGFyYW0gZW50cnlOdW1iZXIgRW50cnkgbnVtYmVyIChmb3IgZGlzcGxheSlcbiAgICogQHJldHVybnMgRm9ybWF0dGVkIGVudHJ5IHRleHRcbiAgICovXG4gIHByaXZhdGUgZm9ybWF0TG9nRW50cnkoZW50cnk6IFZhbGlkYXRpb25Mb2dFbnRyeSwgZW50cnlOdW1iZXI6IG51bWJlcik6IHN0cmluZyB7XG4gICAgbGV0IHRleHQgPSBgWyR7ZW50cnkudGltZXN0YW1wfV0gVmFsaWRhdGlvbiBGYWlsZWQgLSBTb3VyY2U6ICR7ZW50cnkuc291cmNlfVxcbmA7XG4gICAgXG4gICAgLy8gQWRkIGNvbnRleHQgaW5mb3JtYXRpb24gaWYgYXZhaWxhYmxlXG4gICAgaWYgKGVudHJ5LmNvbnRleHQpIHtcbiAgICAgIGlmIChlbnRyeS5jb250ZXh0LmZpbGVOYW1lKSB7XG4gICAgICAgIHRleHQgKz0gYEZpbGU6ICR7ZW50cnkuY29udGV4dC5maWxlTmFtZX1cXG5gO1xuICAgICAgfVxuICAgICAgaWYgKGVudHJ5LmNvbnRleHQuc3RvcmFnZUtleSkge1xuICAgICAgICB0ZXh0ICs9IGBTdG9yYWdlIEtleTogJHtlbnRyeS5jb250ZXh0LnN0b3JhZ2VLZXl9XFxuYDtcbiAgICAgIH1cbiAgICAgIGlmIChlbnRyeS5jb250ZXh0LmNvbmZpZ1NuaXBwZXQpIHtcbiAgICAgICAgdGV4dCArPSBgQ29uZmlnIFNuaXBwZXQ6ICR7ZW50cnkuY29udGV4dC5jb25maWdTbmlwcGV0fVxcbmA7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGV4dCArPSBgJHsn4pSBJy5yZXBlYXQoODApfVxcbmA7XG5cbiAgICAvLyBGb3JtYXQgZWFjaCBlcnJvclxuICAgIGVudHJ5LmVycm9ycy5mb3JFYWNoKChlcnJvciwgZXJyb3JJbmRleCkgPT4ge1xuICAgICAgdGV4dCArPSBgRXJyb3IgJHtlcnJvckluZGV4ICsgMX06XFxuYDtcbiAgICAgIFxuICAgICAgaWYgKGVycm9yLmZpZWxkKSB7XG4gICAgICAgIHRleHQgKz0gYCAgRmllbGQ6ICR7ZXJyb3IuZmllbGR9XFxuYDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKGVycm9yLnBhdGgpIHtcbiAgICAgICAgdGV4dCArPSBgICBQYXRoOiAke2Vycm9yLnBhdGh9XFxuYDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKGVycm9yLmNvZGUpIHtcbiAgICAgICAgdGV4dCArPSBgICBDb2RlOiAke2Vycm9yLmNvZGV9XFxuYDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKGVycm9yLm1lc3NhZ2UpIHtcbiAgICAgICAgdGV4dCArPSBgICBNZXNzYWdlOiAke2Vycm9yLm1lc3NhZ2V9XFxuYDtcbiAgICAgIH1cbiAgICAgIFxuICAgICAgaWYgKGVycm9yLnZhbHVlICE9PSB1bmRlZmluZWQgJiYgZXJyb3IudmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgY29uc3QgdmFsdWVTdHIgPSB0eXBlb2YgZXJyb3IudmFsdWUgPT09ICdvYmplY3QnIFxuICAgICAgICAgID8gSlNPTi5zdHJpbmdpZnkoZXJyb3IudmFsdWUsIG51bGwsIDIpLnNwbGl0KCdcXG4nKS5tYXAobGluZSA9PiBgICAgICR7bGluZX1gKS5qb2luKCdcXG4nKVxuICAgICAgICAgIDogU3RyaW5nKGVycm9yLnZhbHVlKTtcbiAgICAgICAgdGV4dCArPSBgICBWYWx1ZTogJHt2YWx1ZVN0cn1cXG5gO1xuICAgICAgfVxuICAgICAgXG4gICAgICB0ZXh0ICs9ICdcXG4nO1xuICAgIH0pO1xuXG4gICAgdGV4dCArPSBgJHsn4pSBJy5yZXBlYXQoODApfVxcbmA7XG5cbiAgICByZXR1cm4gdGV4dDtcbiAgfVxuXG4gIC8qKlxuICAgKiBEb3dubG9hZCBsb2cgZmlsZVxuICAgKiBAcGFyYW0gZmlsZW5hbWUgT3B0aW9uYWwgZmlsZW5hbWUgKGRlZmF1bHQ6ICdzbWFydC10YWJsZS12YWxpZGF0aW9uLWVycm9ycy5sb2cnKVxuICAgKi9cbiAgZG93bmxvYWRMb2dGaWxlKGZpbGVuYW1lOiBzdHJpbmcgPSAnc21hcnQtdGFibGUtdmFsaWRhdGlvbi1lcnJvcnMubG9nJyk6IHZvaWQge1xuICAgIGNvbnN0IGxvZ1RleHQgPSB0aGlzLmZvcm1hdExvZ0FzVGV4dCgpO1xuICAgIGNvbnN0IGJsb2IgPSBuZXcgQmxvYihbbG9nVGV4dF0sIHsgdHlwZTogJ3RleHQvcGxhaW4nIH0pO1xuICAgIGNvbnN0IHVybCA9IFVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG4gICAgY29uc3QgbGluayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICBsaW5rLmhyZWYgPSB1cmw7XG4gICAgbGluay5kb3dubG9hZCA9IGZpbGVuYW1lO1xuICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQobGluayk7XG4gICAgbGluay5jbGljaygpO1xuICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQobGluayk7XG4gICAgVVJMLnJldm9rZU9iamVjdFVSTCh1cmwpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFyIGFsbCBsb2cgZW50cmllc1xuICAgKi9cbiAgY2xlYXJMb2coKTogdm9pZCB7XG4gICAgLy8gQ2FuY2VsIGFueSBwZW5kaW5nIGRvd25sb2FkXG4gICAgaWYgKHRoaXMuZG93bmxvYWRUaW1lb3V0SWQgIT09IG51bGwpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLmRvd25sb2FkVGltZW91dElkKTtcbiAgICAgIHRoaXMuZG93bmxvYWRUaW1lb3V0SWQgPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLmxvZ0VudHJpZXMgPSBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgbnVtYmVyIG9mIGxvZyBlbnRyaWVzXG4gICAqIEByZXR1cm5zIE51bWJlciBvZiBsb2cgZW50cmllc1xuICAgKi9cbiAgZ2V0TG9nU2l6ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmxvZ0VudHJpZXMubGVuZ3RoO1xuICB9XG59XG5cbiJdfQ==
|