@fgv/ts-res-ui-components 5.0.0-10

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.
Files changed (231) hide show
  1. package/.rush/temp/03c8b056281d9db0a97d8a6e25eea798a160d393.tar.log +271 -0
  2. package/.rush/temp/chunked-rush-logs/ts-res-ui-components.build.chunks.jsonl +9 -0
  3. package/.rush/temp/operation/build/all.log +9 -0
  4. package/.rush/temp/operation/build/log-chunks.jsonl +9 -0
  5. package/.rush/temp/operation/build/state.json +3 -0
  6. package/.rush/temp/shrinkwrap-deps.json +1111 -0
  7. package/README.md +18 -0
  8. package/REFACTORING_PLAN.md +171 -0
  9. package/config/jest.config.json +16 -0
  10. package/config/jest.setup.js +64 -0
  11. package/config/rig.json +16 -0
  12. package/lib/components/common/QualifierContextControl.d.ts +14 -0
  13. package/lib/components/common/QualifierContextControl.d.ts.map +1 -0
  14. package/lib/components/common/QualifierContextControl.js +78 -0
  15. package/lib/components/common/QualifierContextControl.js.map +1 -0
  16. package/lib/components/common/ResourceListView.d.ts +11 -0
  17. package/lib/components/common/ResourceListView.d.ts.map +1 -0
  18. package/lib/components/common/ResourceListView.js +20 -0
  19. package/lib/components/common/ResourceListView.js.map +1 -0
  20. package/lib/components/common/ResourceTreeView.d.ts +12 -0
  21. package/lib/components/common/ResourceTreeView.d.ts.map +1 -0
  22. package/lib/components/common/ResourceTreeView.js +162 -0
  23. package/lib/components/common/ResourceTreeView.js.map +1 -0
  24. package/lib/components/forms/HierarchyEditor.d.ts +10 -0
  25. package/lib/components/forms/HierarchyEditor.d.ts.map +1 -0
  26. package/lib/components/forms/HierarchyEditor.js +106 -0
  27. package/lib/components/forms/HierarchyEditor.js.map +1 -0
  28. package/lib/components/forms/QualifierEditForm.d.ts +11 -0
  29. package/lib/components/forms/QualifierEditForm.d.ts.map +1 -0
  30. package/lib/components/forms/QualifierEditForm.js +181 -0
  31. package/lib/components/forms/QualifierEditForm.js.map +1 -0
  32. package/lib/components/forms/QualifierTypeEditForm.d.ts +10 -0
  33. package/lib/components/forms/QualifierTypeEditForm.d.ts.map +1 -0
  34. package/lib/components/forms/QualifierTypeEditForm.js +172 -0
  35. package/lib/components/forms/QualifierTypeEditForm.js.map +1 -0
  36. package/lib/components/forms/ResourceTypeEditForm.d.ts +10 -0
  37. package/lib/components/forms/ResourceTypeEditForm.d.ts.map +1 -0
  38. package/lib/components/forms/ResourceTypeEditForm.js +188 -0
  39. package/lib/components/forms/ResourceTypeEditForm.js.map +1 -0
  40. package/lib/components/forms/index.d.ts +9 -0
  41. package/lib/components/forms/index.d.ts.map +1 -0
  42. package/lib/components/forms/index.js +5 -0
  43. package/lib/components/forms/index.js.map +1 -0
  44. package/lib/components/orchestrator/ResourceOrchestrator.d.ts +14 -0
  45. package/lib/components/orchestrator/ResourceOrchestrator.d.ts.map +1 -0
  46. package/lib/components/orchestrator/ResourceOrchestrator.js +278 -0
  47. package/lib/components/orchestrator/ResourceOrchestrator.js.map +1 -0
  48. package/lib/components/views/CompiledView/index.d.ts +5 -0
  49. package/lib/components/views/CompiledView/index.d.ts.map +1 -0
  50. package/lib/components/views/CompiledView/index.js +595 -0
  51. package/lib/components/views/CompiledView/index.js.map +1 -0
  52. package/lib/components/views/ConfigurationView/index.d.ts +5 -0
  53. package/lib/components/views/ConfigurationView/index.d.ts.map +1 -0
  54. package/lib/components/views/ConfigurationView/index.js +363 -0
  55. package/lib/components/views/ConfigurationView/index.js.map +1 -0
  56. package/lib/components/views/FilterView/index.d.ts +5 -0
  57. package/lib/components/views/FilterView/index.d.ts.map +1 -0
  58. package/lib/components/views/FilterView/index.js +463 -0
  59. package/lib/components/views/FilterView/index.js.map +1 -0
  60. package/lib/components/views/ImportView/index.d.ts +5 -0
  61. package/lib/components/views/ImportView/index.d.ts.map +1 -0
  62. package/lib/components/views/ImportView/index.js +514 -0
  63. package/lib/components/views/ImportView/index.js.map +1 -0
  64. package/lib/components/views/ResolutionView/EditableJsonView.d.ts +21 -0
  65. package/lib/components/views/ResolutionView/EditableJsonView.d.ts.map +1 -0
  66. package/lib/components/views/ResolutionView/EditableJsonView.js +109 -0
  67. package/lib/components/views/ResolutionView/EditableJsonView.js.map +1 -0
  68. package/lib/components/views/ResolutionView/ResolutionEditControls.d.ts +19 -0
  69. package/lib/components/views/ResolutionView/ResolutionEditControls.d.ts.map +1 -0
  70. package/lib/components/views/ResolutionView/ResolutionEditControls.js +82 -0
  71. package/lib/components/views/ResolutionView/ResolutionEditControls.js.map +1 -0
  72. package/lib/components/views/ResolutionView/index.d.ts +5 -0
  73. package/lib/components/views/ResolutionView/index.d.ts.map +1 -0
  74. package/lib/components/views/ResolutionView/index.js +255 -0
  75. package/lib/components/views/ResolutionView/index.js.map +1 -0
  76. package/lib/components/views/SourceView/index.d.ts +5 -0
  77. package/lib/components/views/SourceView/index.d.ts.map +1 -0
  78. package/lib/components/views/SourceView/index.js +316 -0
  79. package/lib/components/views/SourceView/index.js.map +1 -0
  80. package/lib/components/views/ZipLoaderView/index.d.ts +5 -0
  81. package/lib/components/views/ZipLoaderView/index.d.ts.map +1 -0
  82. package/lib/components/views/ZipLoaderView/index.js +313 -0
  83. package/lib/components/views/ZipLoaderView/index.js.map +1 -0
  84. package/lib/hooks/useConfigurationState.d.ts +46 -0
  85. package/lib/hooks/useConfigurationState.d.ts.map +1 -0
  86. package/lib/hooks/useConfigurationState.js +239 -0
  87. package/lib/hooks/useConfigurationState.js.map +1 -0
  88. package/lib/hooks/useFilterState.d.ts +7 -0
  89. package/lib/hooks/useFilterState.d.ts.map +1 -0
  90. package/lib/hooks/useFilterState.js +80 -0
  91. package/lib/hooks/useFilterState.js.map +1 -0
  92. package/lib/hooks/useResolutionState.d.ts +8 -0
  93. package/lib/hooks/useResolutionState.d.ts.map +1 -0
  94. package/lib/hooks/useResolutionState.js +253 -0
  95. package/lib/hooks/useResolutionState.js.map +1 -0
  96. package/lib/hooks/useResourceData.d.ts +19 -0
  97. package/lib/hooks/useResourceData.d.ts.map +1 -0
  98. package/lib/hooks/useResourceData.js +368 -0
  99. package/lib/hooks/useResourceData.js.map +1 -0
  100. package/lib/hooks/useViewState.d.ts +10 -0
  101. package/lib/hooks/useViewState.d.ts.map +1 -0
  102. package/lib/hooks/useViewState.js +29 -0
  103. package/lib/hooks/useViewState.js.map +1 -0
  104. package/lib/index.d.ts +27 -0
  105. package/lib/index.d.ts.map +1 -0
  106. package/lib/index.js +34 -0
  107. package/lib/index.js.map +1 -0
  108. package/lib/test/helpers/testDataLoader.d.ts +37 -0
  109. package/lib/test/helpers/testDataLoader.d.ts.map +1 -0
  110. package/lib/test/helpers/testDataLoader.js +171 -0
  111. package/lib/test/helpers/testDataLoader.js.map +1 -0
  112. package/lib/test/unit/utils/configurationUtils.test.d.ts +2 -0
  113. package/lib/test/unit/utils/configurationUtils.test.d.ts.map +1 -0
  114. package/lib/test/unit/utils/configurationUtils.test.js +497 -0
  115. package/lib/test/unit/utils/configurationUtils.test.js.map +1 -0
  116. package/lib/test/unit/utils/fileProcessing.test.d.ts +2 -0
  117. package/lib/test/unit/utils/fileProcessing.test.d.ts.map +1 -0
  118. package/lib/test/unit/utils/fileProcessing.test.js +321 -0
  119. package/lib/test/unit/utils/fileProcessing.test.js.map +1 -0
  120. package/lib/test/unit/utils/filterResources.test.d.ts +2 -0
  121. package/lib/test/unit/utils/filterResources.test.d.ts.map +1 -0
  122. package/lib/test/unit/utils/filterResources.test.js +403 -0
  123. package/lib/test/unit/utils/filterResources.test.js.map +1 -0
  124. package/lib/test/unit/utils/resolutionEditing.test.d.ts +2 -0
  125. package/lib/test/unit/utils/resolutionEditing.test.d.ts.map +1 -0
  126. package/lib/test/unit/utils/resolutionEditing.test.js +439 -0
  127. package/lib/test/unit/utils/resolutionEditing.test.js.map +1 -0
  128. package/lib/test/unit/utils/resolutionUtils.test.d.ts +2 -0
  129. package/lib/test/unit/utils/resolutionUtils.test.d.ts.map +1 -0
  130. package/lib/test/unit/utils/resolutionUtils.test.js +397 -0
  131. package/lib/test/unit/utils/resolutionUtils.test.js.map +1 -0
  132. package/lib/test/unit/utils/tsResIntegration.test.d.ts +2 -0
  133. package/lib/test/unit/utils/tsResIntegration.test.d.ts.map +1 -0
  134. package/lib/test/unit/utils/tsResIntegration.test.js +376 -0
  135. package/lib/test/unit/utils/tsResIntegration.test.js.map +1 -0
  136. package/lib/types/index.d.ts +251 -0
  137. package/lib/types/index.d.ts.map +1 -0
  138. package/lib/types/index.js +2 -0
  139. package/lib/types/index.js.map +1 -0
  140. package/lib/utils/configurationUtils.d.ts +74 -0
  141. package/lib/utils/configurationUtils.d.ts.map +1 -0
  142. package/lib/utils/configurationUtils.js +359 -0
  143. package/lib/utils/configurationUtils.js.map +1 -0
  144. package/lib/utils/fileProcessing.d.ts +18 -0
  145. package/lib/utils/fileProcessing.d.ts.map +1 -0
  146. package/lib/utils/fileProcessing.js +142 -0
  147. package/lib/utils/fileProcessing.js.map +1 -0
  148. package/lib/utils/filterResources.d.ts +38 -0
  149. package/lib/utils/filterResources.d.ts.map +1 -0
  150. package/lib/utils/filterResources.js +153 -0
  151. package/lib/utils/filterResources.js.map +1 -0
  152. package/lib/utils/resolutionEditing.d.ts +58 -0
  153. package/lib/utils/resolutionEditing.d.ts.map +1 -0
  154. package/lib/utils/resolutionEditing.js +246 -0
  155. package/lib/utils/resolutionEditing.js.map +1 -0
  156. package/lib/utils/resolutionUtils.d.ts +28 -0
  157. package/lib/utils/resolutionUtils.d.ts.map +1 -0
  158. package/lib/utils/resolutionUtils.js +216 -0
  159. package/lib/utils/resolutionUtils.js.map +1 -0
  160. package/lib/utils/tsResIntegration.d.ts +71 -0
  161. package/lib/utils/tsResIntegration.d.ts.map +1 -0
  162. package/lib/utils/tsResIntegration.js +294 -0
  163. package/lib/utils/tsResIntegration.js.map +1 -0
  164. package/lib/utils/zipLoader/browserZipLoader.d.ts +48 -0
  165. package/lib/utils/zipLoader/browserZipLoader.d.ts.map +1 -0
  166. package/lib/utils/zipLoader/browserZipLoader.js +247 -0
  167. package/lib/utils/zipLoader/browserZipLoader.js.map +1 -0
  168. package/lib/utils/zipLoader/index.d.ts +8 -0
  169. package/lib/utils/zipLoader/index.d.ts.map +1 -0
  170. package/lib/utils/zipLoader/index.js +13 -0
  171. package/lib/utils/zipLoader/index.js.map +1 -0
  172. package/lib/utils/zipLoader/nodeZipBuilder.d.ts +55 -0
  173. package/lib/utils/zipLoader/nodeZipBuilder.d.ts.map +1 -0
  174. package/lib/utils/zipLoader/nodeZipBuilder.js +98 -0
  175. package/lib/utils/zipLoader/nodeZipBuilder.js.map +1 -0
  176. package/lib/utils/zipLoader/types.d.ts +139 -0
  177. package/lib/utils/zipLoader/types.d.ts.map +1 -0
  178. package/lib/utils/zipLoader/types.js +2 -0
  179. package/lib/utils/zipLoader/types.js.map +1 -0
  180. package/lib/utils/zipLoader/zipUtils.d.ts +53 -0
  181. package/lib/utils/zipLoader/zipUtils.d.ts.map +1 -0
  182. package/lib/utils/zipLoader/zipUtils.js +229 -0
  183. package/lib/utils/zipLoader/zipUtils.js.map +1 -0
  184. package/package.json +69 -0
  185. package/rush-logs/ts-res-ui-components.build.cache.log +3 -0
  186. package/rush-logs/ts-res-ui-components.build.log +9 -0
  187. package/src/components/common/QualifierContextControl.tsx +151 -0
  188. package/src/components/common/ResourceListView.tsx +63 -0
  189. package/src/components/common/ResourceTreeView.tsx +271 -0
  190. package/src/components/forms/HierarchyEditor.tsx +204 -0
  191. package/src/components/forms/QualifierEditForm.tsx +355 -0
  192. package/src/components/forms/QualifierTypeEditForm.tsx +347 -0
  193. package/src/components/forms/ResourceTypeEditForm.tsx +331 -0
  194. package/src/components/forms/index.ts +11 -0
  195. package/src/components/orchestrator/ResourceOrchestrator.tsx +372 -0
  196. package/src/components/views/CompiledView/index.tsx +922 -0
  197. package/src/components/views/ConfigurationView/index.tsx +800 -0
  198. package/src/components/views/FilterView/index.tsx +825 -0
  199. package/src/components/views/ImportView/index.tsx +717 -0
  200. package/src/components/views/ResolutionView/EditableJsonView.tsx +214 -0
  201. package/src/components/views/ResolutionView/ResolutionEditControls.tsx +170 -0
  202. package/src/components/views/ResolutionView/index.tsx +591 -0
  203. package/src/components/views/SourceView/index.tsx +536 -0
  204. package/src/components/views/ZipLoaderView/index.tsx +485 -0
  205. package/src/hooks/useConfigurationState.ts +374 -0
  206. package/src/hooks/useFilterState.ts +97 -0
  207. package/src/hooks/useResolutionState.ts +355 -0
  208. package/src/hooks/useResourceData.ts +467 -0
  209. package/src/hooks/useViewState.ts +44 -0
  210. package/src/index.ts +45 -0
  211. package/src/test/helpers/testDataLoader.ts +195 -0
  212. package/src/test/unit/utils/configurationUtils.test.ts +630 -0
  213. package/src/test/unit/utils/fileProcessing.test.ts +391 -0
  214. package/src/test/unit/utils/filterResources.test.ts +574 -0
  215. package/src/test/unit/utils/resolutionEditing.test.ts +556 -0
  216. package/src/test/unit/utils/resolutionUtils.test.ts +521 -0
  217. package/src/test/unit/utils/tsResIntegration.test.ts +433 -0
  218. package/src/types/index.ts +322 -0
  219. package/src/utils/configurationUtils.ts +424 -0
  220. package/src/utils/fileProcessing.ts +160 -0
  221. package/src/utils/filterResources.ts +206 -0
  222. package/src/utils/resolutionEditing.ts +319 -0
  223. package/src/utils/resolutionUtils.ts +289 -0
  224. package/src/utils/tsResIntegration.ts +440 -0
  225. package/src/utils/zipLoader/browserZipLoader.ts +319 -0
  226. package/src/utils/zipLoader/index.ts +26 -0
  227. package/src/utils/zipLoader/nodeZipBuilder.ts +153 -0
  228. package/src/utils/zipLoader/types.ts +175 -0
  229. package/src/utils/zipLoader/zipUtils.ts +266 -0
  230. package/temp/build/typescript/ts_gZid87Hu.json +1 -0
  231. package/tsconfig.json +15 -0
@@ -0,0 +1,359 @@
1
+ import { succeed, fail } from '@fgv/ts-utils';
2
+ /**
3
+ * Default system configuration
4
+ */
5
+ export function getDefaultConfiguration() {
6
+ return {
7
+ qualifierTypes: [
8
+ {
9
+ name: 'language',
10
+ systemType: 'language'
11
+ },
12
+ {
13
+ name: 'territory',
14
+ systemType: 'territory'
15
+ }
16
+ ],
17
+ qualifiers: [
18
+ {
19
+ name: 'language',
20
+ typeName: 'language',
21
+ defaultPriority: 100,
22
+ token: 'lang'
23
+ },
24
+ {
25
+ name: 'territory',
26
+ typeName: 'territory',
27
+ defaultPriority: 90,
28
+ token: 'territory'
29
+ }
30
+ ],
31
+ resourceTypes: [
32
+ {
33
+ name: 'string',
34
+ typeName: 'string'
35
+ },
36
+ {
37
+ name: 'object',
38
+ typeName: 'object'
39
+ }
40
+ ]
41
+ };
42
+ }
43
+ /**
44
+ * Validate a system configuration
45
+ */
46
+ export function validateConfiguration(config) {
47
+ const errors = [];
48
+ const warnings = [];
49
+ // Validate qualifierTypes
50
+ if (!config.qualifierTypes || config.qualifierTypes.length === 0) {
51
+ errors.push('Configuration must have at least one qualifier type');
52
+ }
53
+ else {
54
+ const typeNames = new Set();
55
+ config.qualifierTypes.forEach((type, index) => {
56
+ const typeName = type.name || `<type-${index}>`;
57
+ if (!type.name) {
58
+ errors.push(`Qualifier type at index ${index} is missing a name`);
59
+ }
60
+ else if (typeNames.has(type.name)) {
61
+ errors.push(`Duplicate qualifier type name: ${type.name}`);
62
+ }
63
+ else {
64
+ typeNames.add(type.name);
65
+ }
66
+ if (!type.systemType) {
67
+ errors.push(`Qualifier type '${typeName}' is missing systemType`);
68
+ }
69
+ });
70
+ }
71
+ // Validate qualifiers
72
+ if (!config.qualifiers || config.qualifiers.length === 0) {
73
+ warnings.push('Configuration has no qualifiers defined');
74
+ }
75
+ else {
76
+ const qualifierNames = new Set();
77
+ const qualifierTypeNames = new Set(config.qualifierTypes?.map((t) => t.name) || []);
78
+ config.qualifiers.forEach((qualifier, index) => {
79
+ if (!qualifier.name) {
80
+ errors.push(`Qualifier at index ${index} is missing a name`);
81
+ }
82
+ else if (qualifierNames.has(qualifier.name)) {
83
+ errors.push(`Duplicate qualifier name: ${qualifier.name}`);
84
+ }
85
+ else {
86
+ qualifierNames.add(qualifier.name);
87
+ }
88
+ if (!qualifier.typeName) {
89
+ errors.push(`Qualifier '${qualifier.name}' is missing typeName`);
90
+ }
91
+ else if (!qualifierTypeNames.has(qualifier.typeName)) {
92
+ errors.push(`Qualifier '${qualifier.name}' references unknown qualifier type: ${qualifier.typeName}`);
93
+ }
94
+ if (qualifier.defaultPriority === undefined || qualifier.defaultPriority < 0) {
95
+ errors.push(`Qualifier '${qualifier.name}' has invalid defaultPriority`);
96
+ }
97
+ });
98
+ }
99
+ // Validate resourceTypes
100
+ if (!config.resourceTypes || config.resourceTypes.length === 0) {
101
+ errors.push('Configuration must have at least one resource type');
102
+ }
103
+ else {
104
+ const resourceTypeNames = new Set();
105
+ config.resourceTypes.forEach((type, index) => {
106
+ if (!type.name) {
107
+ errors.push(`Resource type at index ${index} is missing a name`);
108
+ }
109
+ else if (resourceTypeNames.has(type.name)) {
110
+ errors.push(`Duplicate resource type name: ${type.name}`);
111
+ }
112
+ else {
113
+ resourceTypeNames.add(type.name);
114
+ }
115
+ if (!type.typeName) {
116
+ errors.push(`Resource type '${type.name}' is missing typeName`);
117
+ }
118
+ });
119
+ }
120
+ return {
121
+ isValid: errors.length === 0,
122
+ errors,
123
+ warnings
124
+ };
125
+ }
126
+ /**
127
+ * Create a deep copy of a configuration
128
+ */
129
+ export function cloneConfiguration(config) {
130
+ return JSON.parse(JSON.stringify(config));
131
+ }
132
+ /**
133
+ * Compare two configurations for equality
134
+ */
135
+ export function compareConfigurations(config1, config2) {
136
+ return JSON.stringify(config1) === JSON.stringify(config2);
137
+ }
138
+ /**
139
+ * Track changes between configurations
140
+ */
141
+ export function trackConfigurationChanges(original, current) {
142
+ const changedSections = [];
143
+ // Check qualifierTypes
144
+ if (JSON.stringify(original.qualifierTypes) !== JSON.stringify(current.qualifierTypes)) {
145
+ changedSections.push('qualifierTypes');
146
+ }
147
+ // Check qualifiers
148
+ if (JSON.stringify(original.qualifiers) !== JSON.stringify(current.qualifiers)) {
149
+ changedSections.push('qualifiers');
150
+ }
151
+ // Check resourceTypes
152
+ if (JSON.stringify(original.resourceTypes) !== JSON.stringify(current.resourceTypes)) {
153
+ changedSections.push('resourceTypes');
154
+ }
155
+ return {
156
+ hasChanges: changedSections.length > 0,
157
+ changedSections,
158
+ timestamp: new Date()
159
+ };
160
+ }
161
+ /**
162
+ * Export configuration to JSON string
163
+ */
164
+ export function exportConfiguration(config, options = { format: 'json', pretty: true }) {
165
+ try {
166
+ if (options.format === 'json') {
167
+ return succeed(JSON.stringify(config, null, options.pretty ? 2 : 0));
168
+ }
169
+ else {
170
+ return fail('YAML export not implemented yet');
171
+ }
172
+ }
173
+ catch (error) {
174
+ return fail(`Failed to export configuration: ${error instanceof Error ? error.message : String(error)}`);
175
+ }
176
+ }
177
+ /**
178
+ * Import configuration from JSON string
179
+ */
180
+ export function importConfiguration(data) {
181
+ try {
182
+ const parsed = JSON.parse(data);
183
+ // Basic structure validation
184
+ if (!parsed || typeof parsed !== 'object') {
185
+ return fail('Invalid configuration: not an object');
186
+ }
187
+ const validation = validateConfiguration(parsed);
188
+ if (!validation.isValid) {
189
+ return fail(`Invalid configuration: ${validation.errors.join(', ')}`);
190
+ }
191
+ return succeed(parsed);
192
+ }
193
+ catch (error) {
194
+ return fail(`Failed to parse configuration: ${error instanceof Error ? error.message : String(error)}`);
195
+ }
196
+ }
197
+ /**
198
+ * Get predefined configuration templates
199
+ */
200
+ export function getConfigurationTemplates() {
201
+ return [
202
+ {
203
+ id: 'basic',
204
+ name: 'Basic Configuration',
205
+ description: 'Simple language and territory-based configuration',
206
+ category: 'basic',
207
+ configuration: getDefaultConfiguration()
208
+ },
209
+ {
210
+ id: 'multilingual',
211
+ name: 'Multilingual Application',
212
+ description: 'Configuration for applications with multiple languages and regions',
213
+ category: 'intermediate',
214
+ configuration: {
215
+ qualifierTypes: [
216
+ {
217
+ name: 'language',
218
+ systemType: 'language'
219
+ },
220
+ {
221
+ name: 'territory',
222
+ systemType: 'territory'
223
+ },
224
+ {
225
+ name: 'platform',
226
+ systemType: 'literal'
227
+ }
228
+ ],
229
+ qualifiers: [
230
+ {
231
+ name: 'language',
232
+ typeName: 'language',
233
+ defaultPriority: 100,
234
+ token: 'lang'
235
+ },
236
+ {
237
+ name: 'territory',
238
+ typeName: 'territory',
239
+ defaultPriority: 90,
240
+ token: 'territory'
241
+ },
242
+ {
243
+ name: 'platform',
244
+ typeName: 'platform',
245
+ defaultPriority: 80,
246
+ token: 'platform'
247
+ }
248
+ ],
249
+ resourceTypes: [
250
+ {
251
+ name: 'string',
252
+ typeName: 'string'
253
+ },
254
+ {
255
+ name: 'object',
256
+ typeName: 'object'
257
+ },
258
+ {
259
+ name: 'array',
260
+ typeName: 'array'
261
+ }
262
+ ]
263
+ }
264
+ },
265
+ {
266
+ id: 'enterprise',
267
+ name: 'Enterprise Configuration',
268
+ description: 'Complex configuration for enterprise applications with roles and departments',
269
+ category: 'enterprise',
270
+ configuration: {
271
+ qualifierTypes: [
272
+ {
273
+ name: 'language',
274
+ systemType: 'language'
275
+ },
276
+ {
277
+ name: 'territory',
278
+ systemType: 'territory'
279
+ },
280
+ {
281
+ name: 'role',
282
+ systemType: 'literal'
283
+ },
284
+ {
285
+ name: 'department',
286
+ systemType: 'literal'
287
+ },
288
+ {
289
+ name: 'securityLevel',
290
+ systemType: 'literal'
291
+ }
292
+ ],
293
+ qualifiers: [
294
+ {
295
+ name: 'language',
296
+ typeName: 'language',
297
+ defaultPriority: 100,
298
+ token: 'lang'
299
+ },
300
+ {
301
+ name: 'territory',
302
+ typeName: 'territory',
303
+ defaultPriority: 95,
304
+ token: 'territory'
305
+ },
306
+ {
307
+ name: 'role',
308
+ typeName: 'role',
309
+ defaultPriority: 90,
310
+ token: 'role'
311
+ },
312
+ {
313
+ name: 'department',
314
+ typeName: 'department',
315
+ defaultPriority: 85,
316
+ token: 'dept'
317
+ },
318
+ {
319
+ name: 'securityLevel',
320
+ typeName: 'securityLevel',
321
+ defaultPriority: 80,
322
+ token: 'security'
323
+ }
324
+ ],
325
+ resourceTypes: [
326
+ {
327
+ name: 'string',
328
+ typeName: 'string'
329
+ },
330
+ {
331
+ name: 'localizedString',
332
+ typeName: 'string'
333
+ },
334
+ {
335
+ name: 'config',
336
+ typeName: 'object'
337
+ },
338
+ {
339
+ name: 'permissions',
340
+ typeName: 'array'
341
+ },
342
+ {
343
+ name: 'settings',
344
+ typeName: 'object'
345
+ }
346
+ ]
347
+ }
348
+ }
349
+ ];
350
+ }
351
+ /**
352
+ * Generate a filename for configuration export
353
+ */
354
+ export function generateConfigurationFilename(configName, format = 'json') {
355
+ const timestamp = new Date().toISOString().slice(0, 19).replace(/[:.]/g, '-');
356
+ const baseName = configName ? `${configName}-config` : 'ts-res-config';
357
+ return `${baseName}-${timestamp}.${format}`;
358
+ }
359
+ //# sourceMappingURL=configurationUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configurationUtils.js","sourceRoot":"","sources":["../../src/utils/configurationUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Result, succeed, fail } from '@fgv/ts-utils';\nimport { Config, QualifierTypes, Qualifiers, ResourceTypes } from '@fgv/ts-res';\n\n/**\n * Configuration change tracking\n */\nexport interface ConfigurationChanges {\n hasChanges: boolean;\n changedSections: string[];\n timestamp: Date;\n}\n\n/**\n * Configuration validation result\n */\nexport interface ConfigurationValidationResult {\n isValid: boolean;\n errors: string[];\n warnings: string[];\n}\n\n/**\n * Configuration export options\n */\nexport interface ConfigurationExportOptions {\n format: 'json' | 'yaml';\n pretty: boolean;\n includeComments?: boolean;\n filename?: string;\n}\n\n/**\n * Predefined configuration templates\n */\nexport interface ConfigurationTemplate {\n id: string;\n name: string;\n description: string;\n configuration: Config.Model.ISystemConfiguration;\n category: 'basic' | 'intermediate' | 'advanced' | 'enterprise';\n}\n\n/**\n * Default system configuration\n */\nexport function getDefaultConfiguration(): Config.Model.ISystemConfiguration {\n return {\n qualifierTypes: [\n {\n name: 'language',\n systemType: 'language'\n },\n {\n name: 'territory',\n systemType: 'territory'\n }\n ],\n qualifiers: [\n {\n name: 'language',\n typeName: 'language',\n defaultPriority: 100,\n token: 'lang'\n },\n {\n name: 'territory',\n typeName: 'territory',\n defaultPriority: 90,\n token: 'territory'\n }\n ],\n resourceTypes: [\n {\n name: 'string',\n typeName: 'string'\n },\n {\n name: 'object',\n typeName: 'object'\n }\n ]\n };\n}\n\n/**\n * Validate a system configuration\n */\nexport function validateConfiguration(\n config: Config.Model.ISystemConfiguration\n): ConfigurationValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n // Validate qualifierTypes\n if (!config.qualifierTypes || config.qualifierTypes.length === 0) {\n errors.push('Configuration must have at least one qualifier type');\n } else {\n const typeNames = new Set<string>();\n (config.qualifierTypes as QualifierTypes.Config.ISystemQualifierTypeConfig[]).forEach((type, index) => {\n const typeName = type.name || `<type-${index}>`;\n\n if (!type.name) {\n errors.push(`Qualifier type at index ${index} is missing a name`);\n } else if (typeNames.has(type.name)) {\n errors.push(`Duplicate qualifier type name: ${type.name}`);\n } else {\n typeNames.add(type.name);\n }\n\n if (!type.systemType) {\n errors.push(`Qualifier type '${typeName}' is missing systemType`);\n }\n });\n }\n\n // Validate qualifiers\n if (!config.qualifiers || config.qualifiers.length === 0) {\n warnings.push('Configuration has no qualifiers defined');\n } else {\n const qualifierNames = new Set<string>();\n const qualifierTypeNames = new Set(config.qualifierTypes?.map((t) => t.name) || []);\n\n (config.qualifiers as Qualifiers.IQualifierDecl[]).forEach((qualifier, index) => {\n if (!qualifier.name) {\n errors.push(`Qualifier at index ${index} is missing a name`);\n } else if (qualifierNames.has(qualifier.name)) {\n errors.push(`Duplicate qualifier name: ${qualifier.name}`);\n } else {\n qualifierNames.add(qualifier.name);\n }\n\n if (!qualifier.typeName) {\n errors.push(`Qualifier '${qualifier.name}' is missing typeName`);\n } else if (!qualifierTypeNames.has(qualifier.typeName)) {\n errors.push(`Qualifier '${qualifier.name}' references unknown qualifier type: ${qualifier.typeName}`);\n }\n\n if (qualifier.defaultPriority === undefined || qualifier.defaultPriority < 0) {\n errors.push(`Qualifier '${qualifier.name}' has invalid defaultPriority`);\n }\n });\n }\n\n // Validate resourceTypes\n if (!config.resourceTypes || config.resourceTypes.length === 0) {\n errors.push('Configuration must have at least one resource type');\n } else {\n const resourceTypeNames = new Set<string>();\n (config.resourceTypes as ResourceTypes.Config.IResourceTypeConfig[]).forEach((type, index) => {\n if (!type.name) {\n errors.push(`Resource type at index ${index} is missing a name`);\n } else if (resourceTypeNames.has(type.name)) {\n errors.push(`Duplicate resource type name: ${type.name}`);\n } else {\n resourceTypeNames.add(type.name);\n }\n\n if (!type.typeName) {\n errors.push(`Resource type '${type.name}' is missing typeName`);\n }\n });\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n warnings\n };\n}\n\n/**\n * Create a deep copy of a configuration\n */\nexport function cloneConfiguration(\n config: Config.Model.ISystemConfiguration\n): Config.Model.ISystemConfiguration {\n return JSON.parse(JSON.stringify(config));\n}\n\n/**\n * Compare two configurations for equality\n */\nexport function compareConfigurations(\n config1: Config.Model.ISystemConfiguration,\n config2: Config.Model.ISystemConfiguration\n): boolean {\n return JSON.stringify(config1) === JSON.stringify(config2);\n}\n\n/**\n * Track changes between configurations\n */\nexport function trackConfigurationChanges(\n original: Config.Model.ISystemConfiguration,\n current: Config.Model.ISystemConfiguration\n): ConfigurationChanges {\n const changedSections: string[] = [];\n\n // Check qualifierTypes\n if (JSON.stringify(original.qualifierTypes) !== JSON.stringify(current.qualifierTypes)) {\n changedSections.push('qualifierTypes');\n }\n\n // Check qualifiers\n if (JSON.stringify(original.qualifiers) !== JSON.stringify(current.qualifiers)) {\n changedSections.push('qualifiers');\n }\n\n // Check resourceTypes\n if (JSON.stringify(original.resourceTypes) !== JSON.stringify(current.resourceTypes)) {\n changedSections.push('resourceTypes');\n }\n\n return {\n hasChanges: changedSections.length > 0,\n changedSections,\n timestamp: new Date()\n };\n}\n\n/**\n * Export configuration to JSON string\n */\nexport function exportConfiguration(\n config: Config.Model.ISystemConfiguration,\n options: ConfigurationExportOptions = { format: 'json', pretty: true }\n): Result<string> {\n try {\n if (options.format === 'json') {\n return succeed(JSON.stringify(config, null, options.pretty ? 2 : 0));\n } else {\n return fail('YAML export not implemented yet');\n }\n } catch (error) {\n return fail(`Failed to export configuration: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Import configuration from JSON string\n */\nexport function importConfiguration(data: string): Result<Config.Model.ISystemConfiguration> {\n try {\n const parsed = JSON.parse(data);\n\n // Basic structure validation\n if (!parsed || typeof parsed !== 'object') {\n return fail('Invalid configuration: not an object');\n }\n\n const validation = validateConfiguration(parsed);\n if (!validation.isValid) {\n return fail(`Invalid configuration: ${validation.errors.join(', ')}`);\n }\n\n return succeed(parsed as Config.Model.ISystemConfiguration);\n } catch (error) {\n return fail(`Failed to parse configuration: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Get predefined configuration templates\n */\nexport function getConfigurationTemplates(): ConfigurationTemplate[] {\n return [\n {\n id: 'basic',\n name: 'Basic Configuration',\n description: 'Simple language and territory-based configuration',\n category: 'basic',\n configuration: getDefaultConfiguration()\n },\n {\n id: 'multilingual',\n name: 'Multilingual Application',\n description: 'Configuration for applications with multiple languages and regions',\n category: 'intermediate',\n configuration: {\n qualifierTypes: [\n {\n name: 'language',\n systemType: 'language'\n },\n {\n name: 'territory',\n systemType: 'territory'\n },\n {\n name: 'platform',\n systemType: 'literal'\n }\n ],\n qualifiers: [\n {\n name: 'language',\n typeName: 'language',\n defaultPriority: 100,\n token: 'lang'\n },\n {\n name: 'territory',\n typeName: 'territory',\n defaultPriority: 90,\n token: 'territory'\n },\n {\n name: 'platform',\n typeName: 'platform',\n defaultPriority: 80,\n token: 'platform'\n }\n ],\n resourceTypes: [\n {\n name: 'string',\n typeName: 'string'\n },\n {\n name: 'object',\n typeName: 'object'\n },\n {\n name: 'array',\n typeName: 'array'\n }\n ]\n }\n },\n {\n id: 'enterprise',\n name: 'Enterprise Configuration',\n description: 'Complex configuration for enterprise applications with roles and departments',\n category: 'enterprise',\n configuration: {\n qualifierTypes: [\n {\n name: 'language',\n systemType: 'language'\n },\n {\n name: 'territory',\n systemType: 'territory'\n },\n {\n name: 'role',\n systemType: 'literal'\n },\n {\n name: 'department',\n systemType: 'literal'\n },\n {\n name: 'securityLevel',\n systemType: 'literal'\n }\n ],\n qualifiers: [\n {\n name: 'language',\n typeName: 'language',\n defaultPriority: 100,\n token: 'lang'\n },\n {\n name: 'territory',\n typeName: 'territory',\n defaultPriority: 95,\n token: 'territory'\n },\n {\n name: 'role',\n typeName: 'role',\n defaultPriority: 90,\n token: 'role'\n },\n {\n name: 'department',\n typeName: 'department',\n defaultPriority: 85,\n token: 'dept'\n },\n {\n name: 'securityLevel',\n typeName: 'securityLevel',\n defaultPriority: 80,\n token: 'security'\n }\n ],\n resourceTypes: [\n {\n name: 'string',\n typeName: 'string'\n },\n {\n name: 'localizedString',\n typeName: 'string'\n },\n {\n name: 'config',\n typeName: 'object'\n },\n {\n name: 'permissions',\n typeName: 'array'\n },\n {\n name: 'settings',\n typeName: 'object'\n }\n ]\n }\n }\n ];\n}\n\n/**\n * Generate a filename for configuration export\n */\nexport function generateConfigurationFilename(configName?: string, format: 'json' | 'yaml' = 'json'): string {\n const timestamp = new Date().toISOString().slice(0, 19).replace(/[:.]/g, '-');\n const baseName = configName ? `${configName}-config` : 'ts-res-config';\n return `${baseName}-${timestamp}.${format}`;\n}\n"]}
@@ -0,0 +1,18 @@
1
+ import { ImportedFile, ImportedDirectory } from '../types';
2
+ /**
3
+ * Read files from file input element
4
+ */
5
+ export declare function readFilesFromInput(files: FileList): Promise<ImportedFile[]>;
6
+ /**
7
+ * Convert flat file list to directory structure
8
+ */
9
+ export declare function filesToDirectory(files: ImportedFile[]): ImportedDirectory;
10
+ /**
11
+ * Export data as JSON file
12
+ */
13
+ export declare function exportAsJson(data: any, filename: string): void;
14
+ /**
15
+ * Export data using File System Access API if available
16
+ */
17
+ export declare function exportUsingFileSystemAPI(data: any, suggestedName: string, description?: string): Promise<boolean>;
18
+ //# sourceMappingURL=fileProcessing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileProcessing.d.ts","sourceRoot":"","sources":["../../src/utils/fileProcessing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE3D;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAejF;AAkBD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,iBAAiB,CA6DzE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAY9D;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,GAAG,EACT,aAAa,EAAE,MAAM,EACrB,WAAW,GAAE,MAAqB,GACjC,OAAO,CAAC,OAAO,CAAC,CA+BlB"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Read files from file input element
3
+ */
4
+ export async function readFilesFromInput(files) {
5
+ const importedFiles = [];
6
+ for (let i = 0; i < files.length; i++) {
7
+ const file = files[i];
8
+ const content = await readFileContent(file);
9
+ importedFiles.push({
10
+ name: file.name,
11
+ path: file.webkitRelativePath || file.name,
12
+ content,
13
+ type: file.type
14
+ });
15
+ }
16
+ return importedFiles;
17
+ }
18
+ /**
19
+ * Read file content as text
20
+ */
21
+ function readFileContent(file) {
22
+ return new Promise((resolve, reject) => {
23
+ const reader = new FileReader();
24
+ reader.onload = (e) => {
25
+ resolve(e.target?.result);
26
+ };
27
+ reader.onerror = (e) => {
28
+ reject(new Error(`Failed to read file ${file.name}: ${e}`));
29
+ };
30
+ reader.readAsText(file);
31
+ });
32
+ }
33
+ /**
34
+ * Convert flat file list to directory structure
35
+ */
36
+ export function filesToDirectory(files) {
37
+ // Group files by directory path
38
+ const filesByPath = new Map();
39
+ const dirPaths = new Set();
40
+ files.forEach((file) => {
41
+ if (file.path) {
42
+ const parts = file.path.split('/');
43
+ if (parts.length > 1) {
44
+ // File is in a subdirectory
45
+ const dirPath = parts.slice(0, -1).join('/');
46
+ dirPaths.add(dirPath);
47
+ if (!filesByPath.has(dirPath)) {
48
+ filesByPath.set(dirPath, []);
49
+ }
50
+ filesByPath.get(dirPath).push({
51
+ ...file,
52
+ name: parts[parts.length - 1]
53
+ });
54
+ }
55
+ else {
56
+ // File is in root
57
+ if (!filesByPath.has('')) {
58
+ filesByPath.set('', []);
59
+ }
60
+ filesByPath.get('').push(file);
61
+ }
62
+ }
63
+ else {
64
+ // No path, add to root
65
+ if (!filesByPath.has('')) {
66
+ filesByPath.set('', []);
67
+ }
68
+ filesByPath.get('').push(file);
69
+ }
70
+ });
71
+ // Build directory tree
72
+ const buildDirectory = (path, name) => {
73
+ const dir = {
74
+ name,
75
+ path,
76
+ files: filesByPath.get(path) || [],
77
+ subdirectories: []
78
+ };
79
+ // Find subdirectories
80
+ const prefix = path ? `${path}/` : '';
81
+ dirPaths.forEach((dirPath) => {
82
+ if (dirPath.startsWith(prefix)) {
83
+ const remaining = dirPath.slice(prefix.length);
84
+ if (remaining && !remaining.includes('/')) {
85
+ // This is a direct subdirectory
86
+ dir.subdirectories.push(buildDirectory(dirPath, remaining));
87
+ }
88
+ }
89
+ });
90
+ return dir;
91
+ };
92
+ return buildDirectory('', 'root');
93
+ }
94
+ /**
95
+ * Export data as JSON file
96
+ */
97
+ export function exportAsJson(data, filename) {
98
+ const json = JSON.stringify(data, null, 2);
99
+ const blob = new Blob([json], { type: 'application/json' });
100
+ const url = URL.createObjectURL(blob);
101
+ const a = document.createElement('a');
102
+ a.href = url;
103
+ a.download = filename;
104
+ document.body.appendChild(a);
105
+ a.click();
106
+ document.body.removeChild(a);
107
+ URL.revokeObjectURL(url);
108
+ }
109
+ /**
110
+ * Export data using File System Access API if available
111
+ */
112
+ export async function exportUsingFileSystemAPI(data, suggestedName, description = 'JSON files') {
113
+ if (!('showSaveFilePicker' in window)) {
114
+ return false;
115
+ }
116
+ try {
117
+ const fileHandle = await window.showSaveFilePicker({
118
+ suggestedName,
119
+ types: [
120
+ {
121
+ description,
122
+ accept: {
123
+ 'application/json': ['.json']
124
+ }
125
+ }
126
+ ]
127
+ });
128
+ const json = JSON.stringify(data, null, 2);
129
+ const writable = await fileHandle.createWritable();
130
+ await writable.write(json);
131
+ await writable.close();
132
+ return true;
133
+ }
134
+ catch (error) {
135
+ // User cancelled or other error
136
+ if (error.name === 'AbortError') {
137
+ return false;
138
+ }
139
+ throw error;
140
+ }
141
+ }
142
+ //# sourceMappingURL=fileProcessing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileProcessing.js","sourceRoot":"","sources":["../../src/utils/fileProcessing.ts"],"names":[],"mappings":"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","sourcesContent":["import { ImportedFile, ImportedDirectory } from '../types';\n\n/**\n * Read files from file input element\n */\nexport async function readFilesFromInput(files: FileList): Promise<ImportedFile[]> {\n const importedFiles: ImportedFile[] = [];\n\n for (let i = 0; i < files.length; i++) {\n const file = files[i];\n const content = await readFileContent(file);\n importedFiles.push({\n name: file.name,\n path: file.webkitRelativePath || file.name,\n content,\n type: file.type\n });\n }\n\n return importedFiles;\n}\n\n/**\n * Read file content as text\n */\nfunction readFileContent(file: File): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = (e) => {\n resolve(e.target?.result as string);\n };\n reader.onerror = (e) => {\n reject(new Error(`Failed to read file ${file.name}: ${e}`));\n };\n reader.readAsText(file);\n });\n}\n\n/**\n * Convert flat file list to directory structure\n */\nexport function filesToDirectory(files: ImportedFile[]): ImportedDirectory {\n // Group files by directory path\n const filesByPath = new Map<string, ImportedFile[]>();\n const dirPaths = new Set<string>();\n\n files.forEach((file) => {\n if (file.path) {\n const parts = file.path.split('/');\n if (parts.length > 1) {\n // File is in a subdirectory\n const dirPath = parts.slice(0, -1).join('/');\n dirPaths.add(dirPath);\n\n if (!filesByPath.has(dirPath)) {\n filesByPath.set(dirPath, []);\n }\n filesByPath.get(dirPath)!.push({\n ...file,\n name: parts[parts.length - 1]\n });\n } else {\n // File is in root\n if (!filesByPath.has('')) {\n filesByPath.set('', []);\n }\n filesByPath.get('')!.push(file);\n }\n } else {\n // No path, add to root\n if (!filesByPath.has('')) {\n filesByPath.set('', []);\n }\n filesByPath.get('')!.push(file);\n }\n });\n\n // Build directory tree\n const buildDirectory = (path: string, name: string): ImportedDirectory => {\n const dir: ImportedDirectory = {\n name,\n path,\n files: filesByPath.get(path) || [],\n subdirectories: []\n };\n\n // Find subdirectories\n const prefix = path ? `${path}/` : '';\n dirPaths.forEach((dirPath) => {\n if (dirPath.startsWith(prefix)) {\n const remaining = dirPath.slice(prefix.length);\n if (remaining && !remaining.includes('/')) {\n // This is a direct subdirectory\n dir.subdirectories!.push(buildDirectory(dirPath, remaining));\n }\n }\n });\n\n return dir;\n };\n\n return buildDirectory('', 'root');\n}\n\n/**\n * Export data as JSON file\n */\nexport function exportAsJson(data: any, filename: string): void {\n const json = JSON.stringify(data, null, 2);\n const blob = new Blob([json], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n\n const a = document.createElement('a');\n a.href = url;\n a.download = filename;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n URL.revokeObjectURL(url);\n}\n\n/**\n * Export data using File System Access API if available\n */\nexport async function exportUsingFileSystemAPI(\n data: any,\n suggestedName: string,\n description: string = 'JSON files'\n): Promise<boolean> {\n if (!('showSaveFilePicker' in window)) {\n return false;\n }\n\n try {\n const fileHandle = await (window as any).showSaveFilePicker({\n suggestedName,\n types: [\n {\n description,\n accept: {\n 'application/json': ['.json']\n }\n }\n ]\n });\n\n const json = JSON.stringify(data, null, 2);\n const writable = await fileHandle.createWritable();\n await writable.write(json);\n await writable.close();\n\n return true;\n } catch (error) {\n // User cancelled or other error\n if ((error as Error).name === 'AbortError') {\n return false;\n }\n throw error;\n }\n}\n"]}
@@ -0,0 +1,38 @@
1
+ import { Result } from '@fgv/ts-utils';
2
+ import { ProcessedResources } from '../types';
3
+ export interface FilterOptions {
4
+ partialContextMatch?: boolean;
5
+ enableDebugLogging?: boolean;
6
+ reduceQualifiers?: boolean;
7
+ }
8
+ export interface FilteredResource {
9
+ id: string;
10
+ originalCandidateCount: number;
11
+ filteredCandidateCount: number;
12
+ hasWarning: boolean;
13
+ }
14
+ export interface FilterResult {
15
+ success: boolean;
16
+ filteredResources: FilteredResource[];
17
+ processedResources?: ProcessedResources;
18
+ error?: string;
19
+ warnings: string[];
20
+ }
21
+ /**
22
+ * Check if filter values object has any meaningful values
23
+ */
24
+ export declare function hasFilterValues(values: Record<string, string | undefined>): boolean;
25
+ /**
26
+ * Get a summary string of active filter values
27
+ */
28
+ export declare function getFilterSummary(values: Record<string, string | undefined>): string;
29
+ /**
30
+ * Creates a filtered resource manager using the ResourceManagerBuilder.clone() method.
31
+ * This is a simplified implementation that leverages the built-in filtering functionality.
32
+ */
33
+ export declare const createFilteredResourceManagerSimple: (originalSystem: ProcessedResources["system"], partialContext: Record<string, string | undefined>, options?: FilterOptions) => Promise<Result<ProcessedResources>>;
34
+ /**
35
+ * Analyze filtered resources compared to original resources
36
+ */
37
+ export declare function analyzeFilteredResources(originalResourceIds: string[], filteredProcessedResources: ProcessedResources, originalProcessedResources: ProcessedResources): FilterResult;
38
+ //# sourceMappingURL=filterResources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filterResources.d.ts","sourceRoot":"","sources":["../../src/utils/filterResources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAiB,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,sBAAsB,EAAE,MAAM,CAAC;IAC/B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;IACtC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AASD;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,OAAO,CAEnF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,CAKnF;AAED;;;GAGG;AACH,eAAO,MAAM,mCAAmC,GAC9C,gBAAgB,kBAAkB,CAAC,QAAQ,CAAC,EAC5C,gBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAClD,UAAS,aAA6C,KACrD,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAqGpC,CAAC;AAEF;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,mBAAmB,EAAE,MAAM,EAAE,EAC7B,0BAA0B,EAAE,kBAAkB,EAC9C,0BAA0B,EAAE,kBAAkB,GAC7C,YAAY,CAsCd"}