@fgv/ts-res 5.0.1-1 → 5.0.1-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 (196) hide show
  1. package/dist/index.browser.js +53 -0
  2. package/dist/index.js +45 -0
  3. package/dist/packlets/bundle/bundleBuilder.js +130 -0
  4. package/dist/packlets/bundle/bundleLoader.js +101 -0
  5. package/dist/packlets/bundle/bundleNormalizer.js +138 -0
  6. package/dist/packlets/bundle/bundleUtils.js +113 -0
  7. package/dist/packlets/bundle/convert.js +75 -0
  8. package/dist/packlets/bundle/index.js +42 -0
  9. package/dist/packlets/bundle/model.js +23 -0
  10. package/dist/packlets/common/conditions.js +47 -0
  11. package/dist/packlets/common/convert.js +172 -0
  12. package/dist/packlets/common/helpers/conditions.js +66 -0
  13. package/dist/packlets/common/helpers/context.js +70 -0
  14. package/dist/packlets/common/helpers/index.js +26 -0
  15. package/dist/packlets/common/helpers/qualifierDefaultValues.js +66 -0
  16. package/dist/packlets/common/helpers/resources.js +93 -0
  17. package/dist/packlets/common/index.js +28 -0
  18. package/dist/packlets/common/resources.js +27 -0
  19. package/dist/packlets/common/validate/conditions.js +544 -0
  20. package/dist/packlets/common/validate/index.js +26 -0
  21. package/dist/packlets/common/validate/regularExpressions.js +84 -0
  22. package/dist/packlets/common/validate/resources.js +209 -0
  23. package/dist/packlets/conditions/condition.js +252 -0
  24. package/dist/packlets/conditions/conditionCollector.js +69 -0
  25. package/dist/packlets/conditions/conditionDecls.js +23 -0
  26. package/dist/packlets/conditions/conditionSet.js +247 -0
  27. package/dist/packlets/conditions/conditionSetCollector.js +89 -0
  28. package/dist/packlets/conditions/conditionSetDecls.js +23 -0
  29. package/dist/packlets/conditions/conditionToken.js +147 -0
  30. package/dist/packlets/conditions/convert/conditionSetDecls.js +51 -0
  31. package/dist/packlets/conditions/convert/decls.js +75 -0
  32. package/dist/packlets/conditions/convert/index.js +24 -0
  33. package/dist/packlets/conditions/index.js +31 -0
  34. package/dist/packlets/config/common.js +78 -0
  35. package/dist/packlets/config/configInitFactory.js +258 -0
  36. package/dist/packlets/config/convert.js +56 -0
  37. package/dist/packlets/config/index.browser.js +34 -0
  38. package/dist/packlets/config/index.js +28 -0
  39. package/dist/packlets/config/json.js +23 -0
  40. package/dist/packlets/config/predefined/default.js +138 -0
  41. package/dist/packlets/config/predefined/extended.js +190 -0
  42. package/dist/packlets/config/predefined/index.js +25 -0
  43. package/dist/packlets/config/systemConfiguration.js +147 -0
  44. package/dist/packlets/context/contextDecls.js +23 -0
  45. package/dist/packlets/context/contextToken.js +202 -0
  46. package/dist/packlets/context/convert/decls.js +91 -0
  47. package/dist/packlets/context/convert/index.js +23 -0
  48. package/dist/packlets/context/index.js +26 -0
  49. package/dist/packlets/decisions/abstractDecision.js +68 -0
  50. package/dist/packlets/decisions/abstractDecisionCollector.js +90 -0
  51. package/dist/packlets/decisions/candidate.js +76 -0
  52. package/dist/packlets/decisions/common.js +23 -0
  53. package/dist/packlets/decisions/concreteDecision.js +111 -0
  54. package/dist/packlets/decisions/decision.js +126 -0
  55. package/dist/packlets/decisions/index.js +28 -0
  56. package/dist/packlets/import/fsItem.js +134 -0
  57. package/dist/packlets/import/importContext.js +129 -0
  58. package/dist/packlets/import/importManager.js +129 -0
  59. package/dist/packlets/import/importable.js +32 -0
  60. package/dist/packlets/import/importers/collectionImporter.js +118 -0
  61. package/dist/packlets/import/importers/fsItemImporter.js +116 -0
  62. package/dist/packlets/import/importers/importer.js +23 -0
  63. package/dist/packlets/import/importers/index.browser.js +29 -0
  64. package/dist/packlets/import/importers/index.js +27 -0
  65. package/dist/packlets/import/importers/jsonImporter.js +94 -0
  66. package/dist/packlets/import/importers/pathImporter.js +84 -0
  67. package/dist/packlets/import/index.browser.js +34 -0
  68. package/dist/packlets/import/index.js +28 -0
  69. package/dist/packlets/qualifier-types/config/convert.js +124 -0
  70. package/dist/packlets/qualifier-types/config/index.js +25 -0
  71. package/dist/packlets/qualifier-types/config/json.js +32 -0
  72. package/dist/packlets/qualifier-types/convert.js +56 -0
  73. package/dist/packlets/qualifier-types/helpers.js +82 -0
  74. package/dist/packlets/qualifier-types/index.js +32 -0
  75. package/dist/packlets/qualifier-types/languageQualifierType.js +142 -0
  76. package/dist/packlets/qualifier-types/literalQualifierType.js +200 -0
  77. package/dist/packlets/qualifier-types/literalValueHierarchy.js +236 -0
  78. package/dist/packlets/qualifier-types/qualifierType.js +184 -0
  79. package/dist/packlets/qualifier-types/qualifierTypeCollector.js +66 -0
  80. package/dist/packlets/qualifier-types/territoryQualifierType.js +200 -0
  81. package/dist/packlets/qualifiers/convert/decls.js +70 -0
  82. package/dist/packlets/qualifiers/convert/index.js +24 -0
  83. package/dist/packlets/qualifiers/convert/qualifier.js +40 -0
  84. package/dist/packlets/qualifiers/index.js +29 -0
  85. package/dist/packlets/qualifiers/qualifier.js +108 -0
  86. package/dist/packlets/qualifiers/qualifierCollector.js +123 -0
  87. package/dist/packlets/qualifiers/qualifierDecl.js +23 -0
  88. package/dist/packlets/qualifiers/qualifierDefaultValueDecls.js +23 -0
  89. package/dist/packlets/qualifiers/qualifierDefaultValueToken.js +175 -0
  90. package/dist/packlets/resource-json/compiled/common.js +23 -0
  91. package/dist/packlets/resource-json/compiled/convert.js +132 -0
  92. package/dist/packlets/resource-json/compiled/index.js +26 -0
  93. package/dist/packlets/resource-json/compiled/json.js +2 -0
  94. package/dist/packlets/resource-json/convert.js +171 -0
  95. package/dist/packlets/resource-json/helpers.js +241 -0
  96. package/dist/packlets/resource-json/index.js +31 -0
  97. package/dist/packlets/resource-json/json.js +36 -0
  98. package/dist/packlets/resource-json/normalized.js +23 -0
  99. package/dist/packlets/resource-json/resourceDeclCollection.js +88 -0
  100. package/dist/packlets/resource-json/resourceDeclContainer.js +23 -0
  101. package/dist/packlets/resource-json/resourceDeclTree.js +94 -0
  102. package/dist/packlets/resource-types/config/convert.js +35 -0
  103. package/dist/packlets/resource-types/config/index.js +25 -0
  104. package/dist/packlets/resource-types/config/json.js +23 -0
  105. package/dist/packlets/resource-types/helpers.js +42 -0
  106. package/dist/packlets/resource-types/index.js +28 -0
  107. package/dist/packlets/resource-types/jsonResourceType.js +66 -0
  108. package/dist/packlets/resource-types/resourceType.js +95 -0
  109. package/dist/packlets/resource-types/resourceTypeCollector.js +61 -0
  110. package/dist/packlets/resources/candidateReducer.js +246 -0
  111. package/dist/packlets/resources/candidateValue.js +92 -0
  112. package/dist/packlets/resources/candidateValueCollector.js +94 -0
  113. package/dist/packlets/resources/common.js +23 -0
  114. package/dist/packlets/resources/deltaGenerator.js +338 -0
  115. package/dist/packlets/resources/index.js +31 -0
  116. package/dist/packlets/resources/resource.js +207 -0
  117. package/dist/packlets/resources/resourceBuilder.js +183 -0
  118. package/dist/packlets/resources/resourceCandidate.js +216 -0
  119. package/dist/packlets/resources/resourceManagerBuilder.js +890 -0
  120. package/dist/packlets/runtime/cacheListener.js +58 -0
  121. package/dist/packlets/runtime/cacheMetrics.js +149 -0
  122. package/dist/packlets/runtime/compiledResourceCollection.js +473 -0
  123. package/dist/packlets/runtime/conditionSetResolutionResult.js +134 -0
  124. package/dist/packlets/runtime/context/contextQualifierProvider.js +29 -0
  125. package/dist/packlets/runtime/context/contextQualifierProviderValidator.js +146 -0
  126. package/dist/packlets/runtime/context/index.js +26 -0
  127. package/dist/packlets/runtime/context/simpleContextQualifierProvider.js +196 -0
  128. package/dist/packlets/runtime/context/validatingSimpleContextQualifierProvider.js +60 -0
  129. package/dist/packlets/runtime/iResourceManager.js +23 -0
  130. package/dist/packlets/runtime/index.js +34 -0
  131. package/dist/packlets/runtime/resource-tree/common.js +23 -0
  132. package/dist/packlets/runtime/resource-tree/index.js +26 -0
  133. package/dist/packlets/runtime/resource-tree/readOnlyResourceTree.js +216 -0
  134. package/dist/packlets/runtime/resource-tree/resourceTreeChildren.js +97 -0
  135. package/dist/packlets/runtime/resource-tree/resourceTreeChildrenValidator.js +161 -0
  136. package/dist/packlets/runtime/resourceResolver.js +481 -0
  137. package/dist/packlets/runtime/resourceTreeResolver.js +220 -0
  138. package/dist/packlets/runtime/validate.js +47 -0
  139. package/dist/packlets/zip-archive/convert.js +100 -0
  140. package/dist/packlets/zip-archive/index.browser.js +54 -0
  141. package/dist/packlets/zip-archive/index.js +47 -0
  142. package/dist/packlets/zip-archive/json.js +23 -0
  143. package/dist/packlets/zip-archive/types.js +36 -0
  144. package/dist/packlets/zip-archive/zipArchiveCreator.js +191 -0
  145. package/dist/packlets/zip-archive/zipArchiveFormat.js +140 -0
  146. package/dist/packlets/zip-archive/zipArchiveLoader.js +282 -0
  147. package/dist/test/data/sample.json +32 -0
  148. package/dist/test/unit/qualifier-types/testQualifierType.js +76 -0
  149. package/dist/test/unit/resource-types/testDerivedResourceType.js +109 -0
  150. package/dist/test/unit/resources/deltaGenerator.helpers.js +282 -0
  151. package/dist/ts-res.d.ts +15 -15
  152. package/dist/tsdoc-metadata.json +1 -1
  153. package/lib/index.browser.d.ts +24 -0
  154. package/lib/index.browser.js +116 -0
  155. package/lib/packlets/common/helpers/resources.d.ts +1 -1
  156. package/lib/packlets/common/helpers/resources.js +3 -2
  157. package/lib/packlets/common/validate/conditions.js +14 -14
  158. package/lib/packlets/common/validate/resources.js +7 -7
  159. package/lib/packlets/conditions/conditionSet.js +1 -1
  160. package/lib/packlets/config/common.js +1 -0
  161. package/lib/packlets/config/configInitFactory.js +1 -0
  162. package/lib/packlets/config/index.browser.d.ts +7 -0
  163. package/lib/packlets/config/index.browser.js +74 -0
  164. package/lib/packlets/config/systemConfiguration.js +1 -0
  165. package/lib/packlets/context/convert/decls.js +1 -1
  166. package/lib/packlets/import/importers/collectionImporter.js +1 -1
  167. package/lib/packlets/import/importers/index.browser.d.ts +4 -0
  168. package/lib/packlets/import/importers/index.browser.js +45 -0
  169. package/lib/packlets/import/importers/jsonImporter.js +1 -1
  170. package/lib/packlets/import/index.browser.d.ts +7 -0
  171. package/lib/packlets/import/index.browser.js +74 -0
  172. package/lib/packlets/qualifier-types/helpers.js +5 -4
  173. package/lib/packlets/qualifier-types/languageQualifierType.d.ts +4 -4
  174. package/lib/packlets/qualifier-types/literalQualifierType.d.ts +4 -4
  175. package/lib/packlets/qualifier-types/literalQualifierType.js +1 -1
  176. package/lib/packlets/qualifier-types/literalValueHierarchy.js +7 -6
  177. package/lib/packlets/qualifier-types/qualifierType.d.ts +5 -5
  178. package/lib/packlets/qualifier-types/qualifierType.js +1 -0
  179. package/lib/packlets/qualifier-types/territoryQualifierType.d.ts +4 -4
  180. package/lib/packlets/qualifier-types/territoryQualifierType.js +1 -1
  181. package/lib/packlets/resource-json/helpers.js +4 -0
  182. package/lib/packlets/resource-types/helpers.js +1 -0
  183. package/lib/packlets/resource-types/resourceType.js +1 -0
  184. package/lib/packlets/resources/candidateValue.js +1 -0
  185. package/lib/packlets/resources/candidateValueCollector.js +4 -2
  186. package/lib/packlets/resources/deltaGenerator.js +8 -10
  187. package/lib/packlets/resources/resourceBuilder.js +4 -0
  188. package/lib/packlets/resources/resourceManagerBuilder.js +6 -0
  189. package/lib/packlets/runtime/compiledResourceCollection.js +1 -0
  190. package/lib/packlets/runtime/context/simpleContextQualifierProvider.js +4 -3
  191. package/lib/packlets/runtime/resource-tree/resourceTreeChildren.js +3 -0
  192. package/lib/packlets/runtime/resourceResolver.js +2 -4
  193. package/lib/packlets/runtime/resourceTreeResolver.js +2 -0
  194. package/lib/packlets/zip-archive/index.browser.d.ts +27 -0
  195. package/lib/packlets/zip-archive/index.browser.js +102 -0
  196. package/package.json +34 -20
@@ -0,0 +1,76 @@
1
+ /*
2
+ * Copyright (c) 2025 Erik Fortune
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ import { captureResult, fail, succeed } from '@fgv/ts-utils';
23
+ import * as TsRes from '../../../index';
24
+ export class TestQualifierType extends TsRes.QualifierTypes.QualifierType {
25
+ constructor(params) {
26
+ var _a;
27
+ super({
28
+ name: (_a = params === null || params === void 0 ? void 0 : params.name) !== null && _a !== void 0 ? _a : 'test',
29
+ allowContextList: (params === null || params === void 0 ? void 0 : params.allowContextList) === 'true',
30
+ index: params === null || params === void 0 ? void 0 : params.index
31
+ });
32
+ this.systemTypeName = TsRes.Convert.qualifierTypeName
33
+ .convert('test')
34
+ .orThrow();
35
+ }
36
+ static create(params) {
37
+ return captureResult(() => new TestQualifierType(params));
38
+ }
39
+ isValidConditionValue(value) {
40
+ return true;
41
+ }
42
+ validateCondition(value, operator) {
43
+ return this.isValidConditionValue(value) ? succeed(value) : fail(`Invalid condition value: ${value}`);
44
+ }
45
+ getConfigurationJson() {
46
+ return succeed({
47
+ name: this.name,
48
+ systemType: 'test',
49
+ configuration: {}
50
+ });
51
+ }
52
+ validateConfigurationJson(from) {
53
+ // Simple validation for test class
54
+ if (typeof from !== 'object' || from === null) {
55
+ return fail('Expected object');
56
+ }
57
+ const obj = from;
58
+ if (typeof obj.name !== 'string') {
59
+ return fail('name must be string');
60
+ }
61
+ if (obj.systemType !== 'test') {
62
+ return fail('systemType must be test');
63
+ }
64
+ return succeed(from);
65
+ }
66
+ _matchOne(condition, context, operator) {
67
+ if (condition === context) {
68
+ return TsRes.PerfectMatch;
69
+ }
70
+ if (condition.toLowerCase() === context.toLowerCase()) {
71
+ return 0.5;
72
+ }
73
+ return TsRes.NoMatch;
74
+ }
75
+ }
76
+ //# sourceMappingURL=testQualifierType.js.map
@@ -0,0 +1,109 @@
1
+ /*
2
+ * Copyright (c) 2025 Erik Fortune
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ import { captureResult, fail, succeed } from '@fgv/ts-utils';
23
+ import { Convert } from '../../../packlets/common';
24
+ // eslint-disable-next-line @rushstack/packlets/mechanics
25
+ import { ResourceType } from '../../../packlets/resource-types/resourceType';
26
+ /**
27
+ * A derived resource type for testing that demonstrates:
28
+ * 1. Custom validation logic
29
+ * 2. Using a resource resolver to look up template values
30
+ * 3. Type-specific defaults and error handling
31
+ */
32
+ export class TestDerivedResourceType extends ResourceType {
33
+ constructor(key, index, template, templateResourceId) {
34
+ super(key, index, template);
35
+ this.systemTypeName = Convert.resourceTypeName
36
+ .convert('test-derived')
37
+ .orThrow();
38
+ this._templateResourceId = templateResourceId;
39
+ }
40
+ /**
41
+ * Factory method to create a new TestDerivedResourceType instance.
42
+ */
43
+ static create(params) {
44
+ var _a;
45
+ return Convert.resourceTypeName.convert((_a = params === null || params === void 0 ? void 0 : params.key) !== null && _a !== void 0 ? _a : 'test-derived').onSuccess((key) => {
46
+ return captureResult(() => new TestDerivedResourceType(key, params === null || params === void 0 ? void 0 : params.index, params === null || params === void 0 ? void 0 : params.template, params === null || params === void 0 ? void 0 : params.templateResourceId));
47
+ });
48
+ }
49
+ /**
50
+ * Validates a resource candidate declaration with custom logic.
51
+ */
52
+ validateDeclaration(props) {
53
+ // Custom validation: merge method must be 'replace' for full candidates
54
+ if (props.completeness === 'full' && props.mergeMethod !== 'replace') {
55
+ return fail(`${this.key}: Full candidates must use 'replace' merge method, got '${props.mergeMethod}'`);
56
+ }
57
+ return this.validate(props.json, props.completeness);
58
+ }
59
+ validate(json, completeness) {
60
+ if (typeof json !== 'object' || json === null || Array.isArray(json)) {
61
+ return fail(`${this.key}: Expected JSON object, got ${typeof json}`);
62
+ }
63
+ const obj = json;
64
+ // Validate required title field for full resources
65
+ if (completeness === 'full' && (typeof obj.title !== 'string' || !obj.title.trim())) {
66
+ return fail(`${this.key}: 'title' field is required and must be a non-empty string`);
67
+ }
68
+ // Validate optional description
69
+ if (obj.description !== undefined && typeof obj.description !== 'string') {
70
+ return fail(`${this.key}: 'description' field must be a string if provided`);
71
+ }
72
+ // Validate optional metadata
73
+ if (obj.metadata !== undefined) {
74
+ if (typeof obj.metadata !== 'object' || obj.metadata === null || Array.isArray(obj.metadata)) {
75
+ return fail(`${this.key}: 'metadata' field must be an object if provided`);
76
+ }
77
+ }
78
+ const result = Object.assign(Object.assign(Object.assign({}, (obj.title && { title: obj.title })), (obj.description && { description: obj.description })), (obj.metadata && { metadata: obj.metadata }));
79
+ return succeed(result);
80
+ }
81
+ /**
82
+ * Override to demonstrate looking up template values from another resource.
83
+ */
84
+ getDefaultTemplateCandidate(json, conditions, resolver) {
85
+ // If a template resource ID is configured and resolver is available, try to resolve it
86
+ if (this._templateResourceId && resolver && !json) {
87
+ return resolver
88
+ .resolveComposedResourceValue(this._templateResourceId)
89
+ .onFailure((error) => fail(`${this.key}: Failed to resolve template resource '${this._templateResourceId}': ${error}`))
90
+ .onSuccess((resolvedValue) => {
91
+ // Use the resolved value as our JSON template
92
+ return super.getDefaultTemplateCandidate(resolvedValue, conditions, resolver);
93
+ });
94
+ }
95
+ // Use provided JSON or fall back to base implementation
96
+ return super.getDefaultTemplateCandidate(json, conditions, resolver);
97
+ }
98
+ /**
99
+ * Override createTemplate to add additional validation for the derived type.
100
+ */
101
+ createTemplate(resourceId, init, conditions, resolver) {
102
+ // Additional validation: warn if trying to use resolver functionality without a resolver
103
+ if (this._templateResourceId && !resolver) {
104
+ return fail(`${this.key}: Template resource ID '${this._templateResourceId}' is configured but no resolver provided`);
105
+ }
106
+ return super.createTemplate(resourceId, init, conditions, resolver);
107
+ }
108
+ }
109
+ //# sourceMappingURL=testDerivedResourceType.js.map
@@ -0,0 +1,282 @@
1
+ /*
2
+ * Copyright (c) 2025 Erik Fortune
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in all
12
+ * copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+ import '@fgv/ts-utils-jest';
23
+ import { succeed, fail } from '@fgv/ts-utils';
24
+ import * as TsRes from '../../../index';
25
+ /**
26
+ * Common test data and setup utilities for DeltaGenerator tests
27
+ */
28
+ // Test resource candidates for baseline and delta scenarios
29
+ export const baselineResources = [
30
+ {
31
+ id: 'greeting.hello',
32
+ json: { message: 'Hello', casual: 'Hi' },
33
+ conditions: { language: 'en' },
34
+ resourceTypeName: 'json'
35
+ },
36
+ {
37
+ id: 'greeting.goodbye',
38
+ json: { message: 'Goodbye', casual: 'Bye' },
39
+ conditions: { language: 'en' },
40
+ resourceTypeName: 'json'
41
+ },
42
+ {
43
+ id: 'numbers.count',
44
+ json: { one: 'one', two: 'two', three: 'three' },
45
+ conditions: { language: 'en' },
46
+ resourceTypeName: 'json'
47
+ }
48
+ ];
49
+ export const deltaResources = [
50
+ // Updated resource - some changes
51
+ {
52
+ id: 'greeting.hello',
53
+ json: { message: 'Hello World', casual: 'Hi there' },
54
+ conditions: { language: 'en' },
55
+ resourceTypeName: 'json'
56
+ },
57
+ // New resource - not in baseline
58
+ {
59
+ id: 'greeting.welcome',
60
+ json: { message: 'Welcome', casual: 'Hey' },
61
+ conditions: { language: 'en' },
62
+ resourceTypeName: 'json'
63
+ },
64
+ // Unchanged resource - identical to baseline
65
+ {
66
+ id: 'numbers.count',
67
+ json: { one: 'one', two: 'two', three: 'three' },
68
+ conditions: { language: 'en' },
69
+ resourceTypeName: 'json'
70
+ }
71
+ ];
72
+ /**
73
+ * Creates the base test setup with qualifier types, qualifiers, and resource types
74
+ */
75
+ export function createBaseTestSetup() {
76
+ // Set up qualifier types
77
+ const qualifierTypes = TsRes.QualifierTypes.QualifierTypeCollector.create({
78
+ qualifierTypes: [
79
+ TsRes.QualifierTypes.LanguageQualifierType.create().orThrow(),
80
+ TsRes.QualifierTypes.TerritoryQualifierType.create().orThrow()
81
+ ]
82
+ }).orThrow();
83
+ // Set up qualifiers
84
+ const qualifiers = TsRes.Qualifiers.QualifierCollector.create({
85
+ qualifierTypes,
86
+ qualifiers: [
87
+ { name: 'language', typeName: 'language', defaultPriority: 100 },
88
+ { name: 'territory', typeName: 'territory', defaultPriority: 90 }
89
+ ]
90
+ }).orThrow();
91
+ // Set up resource types
92
+ const resourceTypes = TsRes.ResourceTypes.ResourceTypeCollector.create({
93
+ resourceTypes: [TsRes.ResourceTypes.JsonResourceType.create().orThrow()]
94
+ }).orThrow();
95
+ // Set up context provider
96
+ const contextProvider = TsRes.Runtime.ValidatingSimpleContextQualifierProvider.create({
97
+ qualifiers,
98
+ qualifierValues: {
99
+ language: 'en',
100
+ territory: 'US'
101
+ }
102
+ }).orThrow();
103
+ return {
104
+ qualifierTypes,
105
+ qualifiers,
106
+ resourceTypes,
107
+ contextProvider
108
+ };
109
+ }
110
+ /**
111
+ * Creates a mock logger for testing
112
+ */
113
+ export function createMockLogger() {
114
+ return {
115
+ logLevel: 'detail',
116
+ log: jest.fn(),
117
+ detail: jest.fn(),
118
+ info: jest.fn(),
119
+ warn: jest.fn(),
120
+ error: jest.fn()
121
+ };
122
+ }
123
+ /**
124
+ * Creates a resource manager with baseline resources
125
+ */
126
+ export function createResourceManagerWithBaseline(qualifiers, resourceTypes, resources = baselineResources) {
127
+ const resourceManager = TsRes.Resources.ResourceManagerBuilder.create({
128
+ qualifiers,
129
+ resourceTypes
130
+ }).orThrow();
131
+ // Add resources
132
+ resources.forEach((resource) => {
133
+ resourceManager.addLooseCandidate(resource).orThrow();
134
+ });
135
+ return resourceManager;
136
+ }
137
+ /**
138
+ * Creates a baseline resolver with the given resources
139
+ */
140
+ export function createBaselineResolver(resourceManager, qualifierTypes, contextProvider) {
141
+ const builtManager = resourceManager.build().orThrow();
142
+ return TsRes.Runtime.ResourceResolver.create({
143
+ resourceManager: builtManager,
144
+ qualifierTypes,
145
+ contextQualifierProvider: contextProvider
146
+ }).orThrow();
147
+ }
148
+ /**
149
+ * Creates a delta resolver with the given resources
150
+ */
151
+ export function createDeltaResolver(resources, qualifiers, resourceTypes, qualifierTypes, contextProvider) {
152
+ const deltaManager = TsRes.Resources.ResourceManagerBuilder.create({
153
+ qualifiers,
154
+ resourceTypes
155
+ }).orThrow();
156
+ resources.forEach((resource) => {
157
+ deltaManager.addLooseCandidate(resource).orThrow();
158
+ });
159
+ const builtDeltaManager = deltaManager.build().orThrow();
160
+ return TsRes.Runtime.ResourceResolver.create({
161
+ resourceManager: builtDeltaManager,
162
+ qualifierTypes,
163
+ contextQualifierProvider: contextProvider
164
+ }).orThrow();
165
+ }
166
+ /**
167
+ * Creates a complete test setup with all required objects
168
+ */
169
+ export function createCompleteTestSetup() {
170
+ const baseSetup = createBaseTestSetup();
171
+ const mockLogger = createMockLogger();
172
+ const resourceManager = createResourceManagerWithBaseline(baseSetup.qualifiers, baseSetup.resourceTypes);
173
+ return Object.assign(Object.assign({}, baseSetup), { resourceManager,
174
+ mockLogger });
175
+ }
176
+ /**
177
+ * Test data for various test scenarios
178
+ */
179
+ export const testData = {
180
+ // Resources with language variations
181
+ languageResources: {
182
+ baseline: [
183
+ {
184
+ id: 'greeting.hello',
185
+ json: { message: 'Hello' },
186
+ conditions: { language: 'en-US' },
187
+ resourceTypeName: 'json'
188
+ },
189
+ {
190
+ id: 'greeting.goodbye',
191
+ json: { message: 'Goodbye' },
192
+ conditions: { language: 'en-US' },
193
+ resourceTypeName: 'json'
194
+ }
195
+ ],
196
+ britishEnglish: [
197
+ {
198
+ id: 'greeting.hello',
199
+ json: { message: 'Hello' },
200
+ conditions: { language: 'en-GB' },
201
+ resourceTypeName: 'json'
202
+ },
203
+ {
204
+ id: 'greeting.goodbye',
205
+ json: { message: 'Cheerio' },
206
+ conditions: { language: 'en-GB' },
207
+ resourceTypeName: 'json'
208
+ },
209
+ {
210
+ id: 'greeting.thanks',
211
+ json: { message: 'Cheers' },
212
+ conditions: { language: 'en-GB' },
213
+ resourceTypeName: 'json'
214
+ }
215
+ ],
216
+ canadianEnglish: [
217
+ {
218
+ id: 'greeting.hello',
219
+ json: { message: 'Hello' },
220
+ conditions: { language: 'en-CA' },
221
+ resourceTypeName: 'json'
222
+ },
223
+ {
224
+ id: 'greeting.goodbye',
225
+ json: { message: 'See ya' },
226
+ conditions: { language: 'en-CA' },
227
+ resourceTypeName: 'json'
228
+ },
229
+ {
230
+ id: 'greeting.apology',
231
+ json: { message: 'Sorry' },
232
+ conditions: { language: 'en-CA' },
233
+ resourceTypeName: 'json'
234
+ }
235
+ ]
236
+ },
237
+ // Empty scenarios
238
+ emptyResources: [],
239
+ // Complex nested resources
240
+ complexResources: [
241
+ {
242
+ id: 'app.config',
243
+ json: {
244
+ settings: {
245
+ theme: 'dark',
246
+ notifications: {
247
+ enabled: true,
248
+ frequency: 'daily',
249
+ types: ['email', 'push']
250
+ }
251
+ },
252
+ metadata: {
253
+ version: '1.0.0',
254
+ lastUpdated: '2025-01-01'
255
+ }
256
+ },
257
+ conditions: { language: 'en' },
258
+ resourceTypeName: 'json'
259
+ }
260
+ ]
261
+ };
262
+ /**
263
+ * Helper to create a failing resolver for error testing
264
+ */
265
+ export function createFailingResolver(errorMessage) {
266
+ return {
267
+ resourceIds: [],
268
+ resolveComposedResourceValue: jest.fn().mockReturnValue(fail(errorMessage)),
269
+ withContext: jest.fn().mockReturnValue(succeed({}))
270
+ };
271
+ }
272
+ /**
273
+ * Helper to create a custom resolver with specific behavior
274
+ */
275
+ export function createCustomResolver(resolveImpl, resourceIds = []) {
276
+ return {
277
+ resourceIds,
278
+ resolveComposedResourceValue: jest.fn().mockImplementation(resolveImpl),
279
+ withContext: jest.fn().mockReturnValue(succeed({}))
280
+ };
281
+ }
282
+ //# sourceMappingURL=deltaGenerator.helpers.js.map
package/dist/ts-res.d.ts CHANGED
@@ -7,7 +7,7 @@ import { FileTree } from '@fgv/ts-json-base';
7
7
  import { Hash } from '@fgv/ts-utils';
8
8
  import { ICollectible } from '@fgv/ts-utils';
9
9
  import { IReadOnlyResultMap } from '@fgv/ts-utils';
10
- import { JsonCompatible } from '@fgv/ts-json-base';
10
+ import { JsonCompatibleType } from '@fgv/ts-json-base';
11
11
  import { JsonObject } from '@fgv/ts-json-base';
12
12
  import { JsonValue } from '@fgv/ts-json-base';
13
13
  import { Logging } from '@fgv/ts-utils';
@@ -2876,7 +2876,7 @@ declare function getDirectoryName(path: string): string;
2876
2876
  /**
2877
2877
  * Gets the name for a resource ID.
2878
2878
  * @param id - The resource ID to get the name for.
2879
- * @returns The resource name if found, or undefined if not.
2879
+ * @returns `Success` with the resource name if found, or `Failure` with an error message if not.
2880
2880
  * @public
2881
2881
  */
2882
2882
  declare function getNameForResourceId(id: string | undefined): Result<ResourceName>;
@@ -4960,13 +4960,13 @@ declare interface IQualifierType<TCFGJSON extends JsonObject = JsonObject> exten
4960
4960
  * Gets the configuration for this qualifier type.
4961
4961
  * @returns `Success` with the configuration if successful, `Failure` with an error message otherwise.
4962
4962
  */
4963
- getConfigurationJson(): Result<JsonCompatible<Config_2.IQualifierTypeConfig<TCFGJSON>>>;
4963
+ getConfigurationJson(): Result<JsonCompatibleType<Config_2.IQualifierTypeConfig<TCFGJSON>>>;
4964
4964
  /**
4965
4965
  * Validates configuration JSON data for this qualifier type.
4966
4966
  * @param from - The unknown data to validate as configuration JSON.
4967
4967
  * @returns `Success` with validated JSON configuration if valid, `Failure` with an error message otherwise.
4968
4968
  */
4969
- validateConfigurationJson(from: unknown): Result<JsonCompatible<Config_2.IQualifierTypeConfig<TCFGJSON>>>;
4969
+ validateConfigurationJson(from: unknown): Result<JsonCompatibleType<Config_2.IQualifierTypeConfig<TCFGJSON>>>;
4970
4970
  }
4971
4971
 
4972
4972
  /**
@@ -6568,7 +6568,7 @@ declare const LanguagePrioritySystemConfiguration: ISystemConfiguration;
6568
6568
  * Accepts a list of language tags in the context by default.
6569
6569
  * @public
6570
6570
  */
6571
- declare class LanguageQualifierType extends QualifierType<JsonCompatible<Config_2.ILanguageQualifierTypeConfig>> {
6571
+ declare class LanguageQualifierType extends QualifierType<JsonCompatibleType<Config_2.ILanguageQualifierTypeConfig>> {
6572
6572
  /**
6573
6573
  * {@inheritdoc QualifierTypes.IQualifierType.systemTypeName}
6574
6574
  */
@@ -6611,11 +6611,11 @@ declare class LanguageQualifierType extends QualifierType<JsonCompatible<Config_
6611
6611
  /**
6612
6612
  * {@inheritdoc QualifierTypes.IQualifierType.getConfigurationJson}
6613
6613
  */
6614
- getConfigurationJson(): Result<JsonCompatible<Config_2.ISystemLanguageQualifierTypeConfig>>;
6614
+ getConfigurationJson(): Result<JsonCompatibleType<Config_2.ISystemLanguageQualifierTypeConfig>>;
6615
6615
  /**
6616
6616
  * {@inheritdoc QualifierTypes.IQualifierType.validateConfigurationJson}
6617
6617
  */
6618
- validateConfigurationJson(from: unknown): Result<JsonCompatible<Config_2.ISystemLanguageQualifierTypeConfig>>;
6618
+ validateConfigurationJson(from: unknown): Result<JsonCompatibleType<Config_2.ISystemLanguageQualifierTypeConfig>>;
6619
6619
  /**
6620
6620
  * Validates a {@link QualifierTypes.Config.ISystemLanguageQualifierTypeConfig | strongly typed configuration object}
6621
6621
  * for this qualifier type.
@@ -6646,7 +6646,7 @@ declare const languageQualifierTypeConfig: ObjectConverter<Model_2.ILanguageQual
6646
6646
  * optionally case-sensitive or matching against an ordered list of values at runtime.
6647
6647
  * @public
6648
6648
  */
6649
- declare class LiteralQualifierType extends QualifierType<JsonCompatible<Config_2.ILiteralQualifierTypeConfig>> {
6649
+ declare class LiteralQualifierType extends QualifierType<JsonCompatibleType<Config_2.ILiteralQualifierTypeConfig>> {
6650
6650
  /**
6651
6651
  * {@inheritdoc QualifierTypes.IQualifierType.systemTypeName}
6652
6652
  */
@@ -6695,11 +6695,11 @@ declare class LiteralQualifierType extends QualifierType<JsonCompatible<Config_2
6695
6695
  /**
6696
6696
  * {@inheritdoc QualifierTypes.IQualifierType.getConfigurationJson}
6697
6697
  */
6698
- getConfigurationJson(): Result<JsonCompatible<Config_2.ISystemLiteralQualifierTypeConfig>>;
6698
+ getConfigurationJson(): Result<JsonCompatibleType<Config_2.ISystemLiteralQualifierTypeConfig>>;
6699
6699
  /**
6700
6700
  * {@inheritdoc QualifierTypes.IQualifierType.validateConfigurationJson}
6701
6701
  */
6702
- validateConfigurationJson(from: unknown): Result<JsonCompatible<Config_2.ISystemLiteralQualifierTypeConfig>>;
6702
+ validateConfigurationJson(from: unknown): Result<JsonCompatibleType<Config_2.ISystemLiteralQualifierTypeConfig>>;
6703
6703
  /**
6704
6704
  * Validates a {@link QualifierTypes.Config.ISystemLiteralQualifierTypeConfig | strongly typed configuration object}
6705
6705
  * for this qualifier type.
@@ -7717,11 +7717,11 @@ export declare abstract class QualifierType<TCFGJSON extends JsonObject = JsonOb
7717
7717
  /**
7718
7718
  * {@inheritdoc QualifierTypes.IQualifierType.getConfigurationJson}
7719
7719
  */
7720
- abstract getConfigurationJson(): Result<JsonCompatible<Config_2.IQualifierTypeConfig<TCFGJSON>>>;
7720
+ abstract getConfigurationJson(): Result<JsonCompatibleType<Config_2.IQualifierTypeConfig<TCFGJSON>>>;
7721
7721
  /**
7722
7722
  * {@inheritdoc QualifierTypes.IQualifierType.validateConfigurationJson}
7723
7723
  */
7724
- abstract validateConfigurationJson(from: unknown): Result<JsonCompatible<Config_2.IQualifierTypeConfig<TCFGJSON>>>;
7724
+ abstract validateConfigurationJson(from: unknown): Result<JsonCompatibleType<Config_2.IQualifierTypeConfig<TCFGJSON>>>;
7725
7725
  /**
7726
7726
  * {@inheritdoc QualifierTypes.IQualifierType.setIndex}
7727
7727
  */
@@ -10010,7 +10010,7 @@ declare const TerritoryPrioritySystemConfiguration: ISystemConfiguration;
10010
10010
  * implementation handles incorrect casing.
10011
10011
  * @public
10012
10012
  */
10013
- declare class TerritoryQualifierType extends QualifierType<JsonCompatible<Config_2.ITerritoryQualifierTypeConfig>> {
10013
+ declare class TerritoryQualifierType extends QualifierType<JsonCompatibleType<Config_2.ITerritoryQualifierTypeConfig>> {
10014
10014
  /**
10015
10015
  * {@inheritdoc QualifierTypes.IQualifierType.systemTypeName}
10016
10016
  */
@@ -10065,11 +10065,11 @@ declare class TerritoryQualifierType extends QualifierType<JsonCompatible<Config
10065
10065
  /**
10066
10066
  * {@inheritdoc QualifierTypes.IQualifierType.getConfigurationJson}
10067
10067
  */
10068
- getConfigurationJson(): Result<JsonCompatible<Config_2.ISystemTerritoryQualifierTypeConfig>>;
10068
+ getConfigurationJson(): Result<JsonCompatibleType<Config_2.ISystemTerritoryQualifierTypeConfig>>;
10069
10069
  /**
10070
10070
  * {@inheritdoc QualifierTypes.IQualifierType.validateConfigurationJson}
10071
10071
  */
10072
- validateConfigurationJson(from: unknown): Result<JsonCompatible<Config_2.ISystemTerritoryQualifierTypeConfig>>;
10072
+ validateConfigurationJson(from: unknown): Result<JsonCompatibleType<Config_2.ISystemTerritoryQualifierTypeConfig>>;
10073
10073
  /**
10074
10074
  * Validates a {@link QualifierTypes.Config.ISystemTerritoryQualifierTypeConfig | strongly typed configuration object}
10075
10075
  * for this qualifier type.
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.52.12"
8
+ "packageVersion": "7.54.0"
9
9
  }
10
10
  ]
11
11
  }
@@ -0,0 +1,24 @@
1
+ import * as Bundle from './packlets/bundle';
2
+ import * as QualifierTypes from './packlets/qualifier-types';
3
+ import * as Qualifiers from './packlets/qualifiers';
4
+ import * as Conditions from './packlets/conditions';
5
+ import * as Config from './packlets/config/index.browser';
6
+ import * as Context from './packlets/context';
7
+ import * as Decisions from './packlets/decisions';
8
+ import * as ResourceJson from './packlets/resource-json';
9
+ import * as Resources from './packlets/resources';
10
+ import * as ResourceTypes from './packlets/resource-types';
11
+ import * as Import from './packlets/import/index.browser';
12
+ import * as Runtime from './packlets/runtime';
13
+ import * as ZipArchive from './packlets/zip-archive/index.browser';
14
+ export * from './packlets/common';
15
+ import { Condition, ConditionSet } from './packlets/conditions';
16
+ import { Decision } from './packlets/decisions';
17
+ import { QualifierType } from './packlets/qualifier-types';
18
+ import { Qualifier } from './packlets/qualifiers';
19
+ import { ResourceType } from './packlets/resource-types';
20
+ import { Resource, ResourceCandidate, ResourceManagerBuilder } from './packlets/resources';
21
+ import { IResourceManager, ResourceResolver } from './packlets/runtime';
22
+ import { BundleBuilder, BundleLoader } from './packlets/bundle';
23
+ export { Bundle, BundleBuilder, BundleLoader, Condition, Conditions, ConditionSet, Config, Context, Decision, Decisions, Import, IResourceManager, Qualifier, QualifierType, QualifierTypes, Qualifiers, Resource, ResourceCandidate, ResourceJson, ResourceResolver, ResourceManagerBuilder, ResourceType, ResourceTypes, Resources, Runtime, ZipArchive };
24
+ //# sourceMappingURL=index.browser.d.ts.map