@fgv/ts-res 5.0.1-9 → 5.0.2-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) 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/tsdoc-metadata.json +1 -1
  152. package/lib/index.browser.d.ts +24 -0
  153. package/lib/index.browser.js +116 -0
  154. package/lib/packlets/config/index.browser.d.ts +7 -0
  155. package/lib/packlets/config/index.browser.js +74 -0
  156. package/lib/packlets/import/importers/index.browser.d.ts +4 -0
  157. package/lib/packlets/import/importers/index.browser.js +45 -0
  158. package/lib/packlets/import/index.browser.d.ts +7 -0
  159. package/lib/packlets/import/index.browser.js +74 -0
  160. package/lib/packlets/zip-archive/index.browser.d.ts +27 -0
  161. package/lib/packlets/zip-archive/index.browser.js +102 -0
  162. package/package.json +25 -7
@@ -0,0 +1,220 @@
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 { MessageAggregator, succeed, fail, captureResult } from '@fgv/ts-utils';
23
+ import { Converters as JsonConverters } from '@fgv/ts-json-base';
24
+ /**
25
+ * Specialized resolver for resource tree operations, providing enhanced APIs for
26
+ * resolving entire resource trees from either resource IDs or pre-built tree nodes.
27
+ *
28
+ * This class provides a clean separation between individual resource resolution
29
+ * (handled by ResourceResolver) and tree-based operations, with support for
30
+ * lazy tree construction and enhanced error handling.
31
+ *
32
+ * @public
33
+ */
34
+ export class ResourceTreeResolver {
35
+ /**
36
+ * Creates a {@link Runtime.ResourceTreeResolver | ResourceTreeResolver} instance.
37
+ * @param resolver - The ResourceResolver to use for individual resource resolution
38
+ */
39
+ constructor(resolver) {
40
+ this.resolver = resolver;
41
+ this._resourceManager = resolver.resourceManager;
42
+ }
43
+ /**
44
+ * Creates a {@link Runtime.ResourceTreeResolver | ResourceTreeResolver} instance.
45
+ * @param resolver - The ResourceResolver to use for individual resource resolution
46
+ */
47
+ static create(resolver) {
48
+ return captureResult(() => new ResourceTreeResolver(resolver));
49
+ }
50
+ /**
51
+ * Gets the built resource tree, building it lazily on first access.
52
+ * @returns The resource tree root
53
+ * @throws Error if no resource manager was provided or tree building fails
54
+ * @public
55
+ */
56
+ get tree() {
57
+ return this._getTree().orThrow();
58
+ }
59
+ /**
60
+ * Implementation for both overloads.
61
+ */
62
+ resolveComposedResourceTree(idOrNode, options) {
63
+ if (typeof idOrNode === 'string') {
64
+ return this._resolveFromResourceId(idOrNode, options);
65
+ }
66
+ return this._resolveFromTreeNode(idOrNode, options);
67
+ }
68
+ _getTree() {
69
+ if (!this._tree) {
70
+ this._tree = this._resourceManager.getBuiltResourceTree();
71
+ }
72
+ return this._tree;
73
+ }
74
+ /**
75
+ * Resolves a tree from a resource ID by first building the tree from the resource manager.
76
+ * @internal
77
+ */
78
+ _resolveFromResourceId(resourceId, options) {
79
+ return this._getTree().onSuccess((tree) => {
80
+ return tree.children.validating
81
+ .getById(resourceId)
82
+ .onFailure((message) => fail(`${resourceId}: Resource not found in resource tree: ${message}`))
83
+ .onSuccess((rootNode) => this._resolveFromTreeNode(rootNode, options));
84
+ });
85
+ }
86
+ /**
87
+ * Resolves a pre-built tree node using the extracted tree resolution logic.
88
+ * @internal
89
+ */
90
+ _resolveFromTreeNode(node, options) {
91
+ var _a, _b;
92
+ const resourceErrorMode = (_a = options === null || options === void 0 ? void 0 : options.onResourceError) !== null && _a !== void 0 ? _a : 'fail';
93
+ const emptyBranchMode = (_b = options === null || options === void 0 ? void 0 : options.onEmptyBranch) !== null && _b !== void 0 ? _b : 'allow';
94
+ // Handle root node with proper Result chaining
95
+ return node.isLeaf
96
+ ? this._processLeafNode(node, '', resourceErrorMode).onSuccess((value) => value !== undefined ? JsonConverters.jsonObject.convert(value) : succeed(undefined))
97
+ : this._processBranchNode(node, '', {
98
+ onResourceError: resourceErrorMode,
99
+ onEmptyBranch: emptyBranchMode
100
+ }).onSuccess((value) => {
101
+ // Only convert undefined to {} if emptyBranchMode is 'allow'
102
+ // For 'omit' mode or custom handlers returning undefined, preserve undefined
103
+ /* c8 ignore next 3 - defense in depth */
104
+ return succeed(value === undefined && emptyBranchMode === 'allow' ? {} : value);
105
+ });
106
+ }
107
+ /**
108
+ * Handles resource resolution errors according to the specified mode.
109
+ * @param resource - The resource that failed to resolve
110
+ * @param message - The error message from the failed resolution
111
+ * @param mode - The error handling mode
112
+ * @param path - The path to the resource in the tree (for error context)
113
+ * @internal
114
+ */
115
+ _handleResourceError(resource, message, mode, path) {
116
+ if (mode === 'ignore') {
117
+ return succeed(undefined);
118
+ }
119
+ if (mode === 'fail') {
120
+ const errorMessage = path ? `${path}: ${message}` : message;
121
+ return fail(errorMessage);
122
+ }
123
+ // Custom handler - pass the resolver for recovery attempts
124
+ return mode(resource, message, this.resolver);
125
+ }
126
+ /**
127
+ * Handles empty branch nodes according to the specified mode.
128
+ * @param node - The empty branch node
129
+ * @param failedChildren - Names of children that failed to resolve
130
+ * @param mode - The empty branch handling mode
131
+ * @param path - The path to the branch in the tree (for error context)
132
+ * @internal
133
+ */
134
+ _handleEmptyBranch(node, failedChildren, mode, path) {
135
+ if (mode === 'omit') {
136
+ return succeed(undefined);
137
+ }
138
+ if (mode === 'allow') {
139
+ return succeed({});
140
+ }
141
+ // Custom handler - pass the resolver for recovery attempts
142
+ return mode(node, failedChildren, this.resolver);
143
+ }
144
+ /**
145
+ * Processes a leaf node by resolving its resource value.
146
+ * @param node - The leaf node to process (must be a leaf node)
147
+ * @param path - The path to the node in the tree
148
+ * @param resourceErrorMode - How to handle resource resolution errors
149
+ * @internal
150
+ */
151
+ _processLeafNode(node, path, resourceErrorMode) {
152
+ /* c8 ignore next 3 - defense in depth */
153
+ if (!node.isLeaf) {
154
+ return fail(`Internal error: processLeafNode called on non-leaf node at ${path}`);
155
+ }
156
+ return this.resolver
157
+ .resolveComposedResourceValue(node.resource)
158
+ .onSuccess((value) => succeed(value))
159
+ .onFailure((message) => this._handleResourceError(node.resource, message, resourceErrorMode, path));
160
+ }
161
+ /**
162
+ * Processes a branch node by recursively resolving all its children.
163
+ * @param node - The branch node to process (must be a branch node)
164
+ * @param path - The path to the node in the tree
165
+ * @param options - Resolution options
166
+ * @internal
167
+ */
168
+ _processBranchNode(node, path, options) {
169
+ var _a, _b;
170
+ /* c8 ignore next 3 - defense in depth */
171
+ if (node.isLeaf) {
172
+ return fail(`Internal error: processBranchNode called on leaf node at ${path}`);
173
+ }
174
+ /* c8 ignore next 2 - ?? is defense in depth */
175
+ const resourceErrorMode = (_a = options.onResourceError) !== null && _a !== void 0 ? _a : 'fail';
176
+ const emptyBranchMode = (_b = options.onEmptyBranch) !== null && _b !== void 0 ? _b : 'allow';
177
+ const aggregator = new MessageAggregator();
178
+ // Process all children
179
+ const childResults = {};
180
+ const failedChildren = [];
181
+ for (const [childName, childNode] of node.children) {
182
+ const childPath = path ? `${path}.${childName}` : childName;
183
+ const childResult = childNode.isLeaf
184
+ ? this._processLeafNode(childNode, childPath, resourceErrorMode)
185
+ : this._processBranchNode(childNode, childPath, options);
186
+ // Process the child result and update our state
187
+ if (childResult.isSuccess()) {
188
+ const value = childResult.value;
189
+ if (value !== undefined) {
190
+ childResults[childName] = value;
191
+ }
192
+ else {
193
+ failedChildren.push(childName);
194
+ }
195
+ }
196
+ else {
197
+ if (resourceErrorMode === 'fail') {
198
+ aggregator.addMessage(childResult.message);
199
+ }
200
+ failedChildren.push(childName);
201
+ }
202
+ }
203
+ // Check for accumulated errors in 'fail' mode
204
+ if (resourceErrorMode === 'fail' && aggregator.hasMessages) {
205
+ return fail(aggregator.toString('; '));
206
+ }
207
+ // Handle empty branch
208
+ if (Object.keys(childResults).length === 0) {
209
+ return this._handleEmptyBranch(node, failedChildren, emptyBranchMode, path).onSuccess((value) => {
210
+ if (value === undefined) {
211
+ return succeed(undefined);
212
+ }
213
+ // Ensure we return JsonObject or undefined
214
+ return JsonConverters.jsonObject.convert(value);
215
+ });
216
+ }
217
+ return succeed(childResults);
218
+ }
219
+ }
220
+ //# sourceMappingURL=resourceTreeResolver.js.map
@@ -0,0 +1,47 @@
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 { Validators } from '@fgv/ts-utils';
23
+ import { Validators as JsonValidators } from '@fgv/ts-json-base';
24
+ import { Validate } from '../common';
25
+ import { ResourceType } from '../resource-types';
26
+ import { ConcreteDecision } from '../decisions';
27
+ /**
28
+ * Validates an {@link Runtime.IResourceCandidate | IResourceCandidate} object.
29
+ * @public
30
+ */
31
+ export const resourceCandidate = Validators.object({
32
+ json: JsonValidators.jsonObject,
33
+ isPartial: Validators.boolean,
34
+ mergeMethod: Validators.isA('resource value merge method', (v) => v === 'augment' || v === 'delete' || v === 'replace')
35
+ });
36
+ /**
37
+ * Validates an {@link Runtime.IResource | IResource} object.
38
+ * @public
39
+ */
40
+ export const resource = Validators.object({
41
+ id: Validators.isA('ResourceId', (v) => typeof v === 'string' && Validate.isValidResourceId(v)),
42
+ name: Validators.isA('ResourceName', (v) => typeof v === 'string' && Validate.isValidResourceName(v)),
43
+ resourceType: Validators.isA('ResourceType instance', (v) => v instanceof ResourceType),
44
+ decision: Validators.isA('ConcreteDecision instance', (v) => v instanceof ConcreteDecision),
45
+ candidates: Validators.arrayOf(resourceCandidate)
46
+ });
47
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1,100 @@
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 { Validators, Converters } from '@fgv/ts-utils';
23
+ import { Convert as ConfigConvert } from '../config';
24
+ /**
25
+ * Validator for ZIP archive input type
26
+ * @public
27
+ */
28
+ export const zipArchiveInputType = Validators.enumeratedValue([
29
+ 'file',
30
+ 'directory'
31
+ ]);
32
+ /**
33
+ * Validator for ZIP archive config type
34
+ * @public
35
+ */
36
+ export const zipArchiveConfigType = Validators.enumeratedValue(['file']);
37
+ /**
38
+ * Validator for ZIP archive input information
39
+ * @public
40
+ */
41
+ export const zipArchiveInputInfo = Validators.object({
42
+ type: zipArchiveInputType,
43
+ originalPath: Validators.string,
44
+ archivePath: Validators.string
45
+ });
46
+ /**
47
+ * Validator for ZIP archive config information
48
+ * @public
49
+ */
50
+ export const zipArchiveConfigInfo = Validators.object({
51
+ type: zipArchiveConfigType,
52
+ originalPath: Validators.string,
53
+ archivePath: Validators.string
54
+ });
55
+ /**
56
+ * Validator for ZIP archive manifest
57
+ * Compatible with existing tools from ts-res-browser-cli
58
+ * @public
59
+ */
60
+ export const zipArchiveManifest = Validators.object({
61
+ timestamp: Validators.string,
62
+ input: zipArchiveInputInfo.optional(),
63
+ config: zipArchiveConfigInfo.optional()
64
+ });
65
+ /**
66
+ * Validator for MIME type strings
67
+ * @public
68
+ */
69
+ export const mimeType = Validators.string;
70
+ /**
71
+ * Converter for imported file
72
+ * @public
73
+ */
74
+ export const importedFile = Converters.strictObject({
75
+ name: Converters.string,
76
+ path: Converters.string,
77
+ content: Converters.string,
78
+ type: Converters.string // MIME type as string
79
+ });
80
+ /**
81
+ * Converter for imported directory structure (recursive)
82
+ * Note: Uses Converter pattern because Validators don't support recursion with self parameter
83
+ * @public
84
+ */
85
+ export const importedDirectory = Converters.generic((from, self, context) => {
86
+ return Converters.strictObject({
87
+ name: Converters.string,
88
+ files: Converters.arrayOf(importedFile),
89
+ subdirectories: Converters.arrayOf(self)
90
+ }).convert(from, context);
91
+ });
92
+ /**
93
+ * Validator for system configuration (delegates to config packlet)
94
+ * This validates that the parsed JSON conforms to the system configuration schema
95
+ * @public
96
+ */
97
+ export const systemConfiguration = Validators.isA('system configuration', (value) => {
98
+ return ConfigConvert.systemConfiguration.convert(value).isSuccess();
99
+ });
100
+ //# sourceMappingURL=convert.js.map
@@ -0,0 +1,54 @@
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
+ /**
23
+ * Browser-safe ZIP archive functionality for ts-res source file archives
24
+ *
25
+ * This packlet provides consolidated ZIP archive creation and loading functionality
26
+ * for source files, compatible with browsers using fflate.
27
+ *
28
+ * @remarks
29
+ * ZIP archives contain source files for resource ingestion with directory
30
+ * structure preserved and optional validation but no processing or transformation.
31
+ * This is distinct from ZIP bundles which contain processed resource output.
32
+ *
33
+ * ZipArchiveCreator supports browser usage when FileTreeItems are provided directly.
34
+ * Methods accepting file paths require Node.js fs access and should not be called in browser.
35
+ *
36
+ * ZipArchiveLoader is fully browser-compatible and works with File API or ArrayBuffer.
37
+ *
38
+ * @packageDocumentation
39
+ */
40
+ import * as Json from './json';
41
+ import * as Convert from './convert';
42
+ // Namespaces
43
+ export { Json, Convert };
44
+ // Core classes (browser-compatible when used with FileTreeItems or buffers)
45
+ export { ZipArchiveCreator } from './zipArchiveCreator';
46
+ export { ZipArchiveLoader } from './zipArchiveLoader';
47
+ // Format utilities
48
+ export { createZipArchiveManifest, parseZipArchiveManifest, validateZipArchiveManifest, parseZipArchiveConfiguration, generateZipArchiveFilename, normalizePath, getDirectoryName, sanitizeFilename, isZipFile } from './zipArchiveFormat';
49
+ // Constants
50
+ export { ZipArchiveConstants } from './types';
51
+ // Note: ZipArchiveCreator._getInputFileTreeItem() and _getConfigFileTreeItem()
52
+ // use FileTree.forFilesystem() internally when given file paths.
53
+ // In browser, provide FileTreeItems directly via IZipArchiveFileTreeOptions.
54
+ //# sourceMappingURL=index.browser.js.map
@@ -0,0 +1,47 @@
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
+ /**
23
+ * ZIP archive functionality for ts-res source file archives
24
+ *
25
+ * This packlet provides consolidated ZIP archive creation and loading functionality
26
+ * for source files, compatible with existing tools while using fflate for
27
+ * universal browser compatibility.
28
+ *
29
+ * @remarks
30
+ * ZIP archives contain source files for resource ingestion with directory
31
+ * structure preserved and optional validation but no processing or transformation.
32
+ * This is distinct from ZIP bundles which contain processed resource output.
33
+ *
34
+ * @packageDocumentation
35
+ */
36
+ import * as Json from './json';
37
+ import * as Convert from './convert';
38
+ // Namespaces
39
+ export { Json, Convert };
40
+ // Core classes
41
+ export { ZipArchiveCreator } from './zipArchiveCreator';
42
+ export { ZipArchiveLoader } from './zipArchiveLoader';
43
+ // Format utilities
44
+ export { createZipArchiveManifest, parseZipArchiveManifest, validateZipArchiveManifest, parseZipArchiveConfiguration, generateZipArchiveFilename, normalizePath, getDirectoryName, sanitizeFilename, isZipFile } from './zipArchiveFormat';
45
+ // Constants
46
+ export { ZipArchiveConstants } from './types';
47
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,23 @@
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
+ export {};
23
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1,36 @@
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
+ /**
23
+ * Constants for ZIP archive structure
24
+ * @public
25
+ */
26
+ export const ZipArchiveConstants = {
27
+ /** Manifest file name */
28
+ MANIFEST_FILE: 'manifest.json',
29
+ /** Configuration file name */
30
+ CONFIG_FILE: 'config.json',
31
+ /** Input files directory */
32
+ INPUT_DIR: 'input',
33
+ /** Configuration files directory */
34
+ CONFIG_DIR: 'config'
35
+ };
36
+ //# sourceMappingURL=types.js.map