@fgv/ts-res 5.0.1-9 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.browser.js +53 -0
- package/dist/index.js +45 -0
- package/dist/packlets/bundle/bundleBuilder.js +130 -0
- package/dist/packlets/bundle/bundleLoader.js +101 -0
- package/dist/packlets/bundle/bundleNormalizer.js +138 -0
- package/dist/packlets/bundle/bundleUtils.js +113 -0
- package/dist/packlets/bundle/convert.js +75 -0
- package/dist/packlets/bundle/index.js +42 -0
- package/dist/packlets/bundle/model.js +23 -0
- package/dist/packlets/common/conditions.js +47 -0
- package/dist/packlets/common/convert.js +172 -0
- package/dist/packlets/common/helpers/conditions.js +66 -0
- package/dist/packlets/common/helpers/context.js +70 -0
- package/dist/packlets/common/helpers/index.js +26 -0
- package/dist/packlets/common/helpers/qualifierDefaultValues.js +66 -0
- package/dist/packlets/common/helpers/resources.js +93 -0
- package/dist/packlets/common/index.js +28 -0
- package/dist/packlets/common/resources.js +27 -0
- package/dist/packlets/common/validate/conditions.js +544 -0
- package/dist/packlets/common/validate/index.js +26 -0
- package/dist/packlets/common/validate/regularExpressions.js +84 -0
- package/dist/packlets/common/validate/resources.js +209 -0
- package/dist/packlets/conditions/condition.js +252 -0
- package/dist/packlets/conditions/conditionCollector.js +69 -0
- package/dist/packlets/conditions/conditionDecls.js +23 -0
- package/dist/packlets/conditions/conditionSet.js +247 -0
- package/dist/packlets/conditions/conditionSetCollector.js +89 -0
- package/dist/packlets/conditions/conditionSetDecls.js +23 -0
- package/dist/packlets/conditions/conditionToken.js +147 -0
- package/dist/packlets/conditions/convert/conditionSetDecls.js +51 -0
- package/dist/packlets/conditions/convert/decls.js +75 -0
- package/dist/packlets/conditions/convert/index.js +24 -0
- package/dist/packlets/conditions/index.js +31 -0
- package/dist/packlets/config/common.js +78 -0
- package/dist/packlets/config/configInitFactory.js +258 -0
- package/dist/packlets/config/convert.js +56 -0
- package/dist/packlets/config/index.browser.js +34 -0
- package/dist/packlets/config/index.js +28 -0
- package/dist/packlets/config/json.js +23 -0
- package/dist/packlets/config/predefined/default.js +138 -0
- package/dist/packlets/config/predefined/extended.js +190 -0
- package/dist/packlets/config/predefined/index.js +25 -0
- package/dist/packlets/config/systemConfiguration.js +147 -0
- package/dist/packlets/context/contextDecls.js +23 -0
- package/dist/packlets/context/contextToken.js +202 -0
- package/dist/packlets/context/convert/decls.js +91 -0
- package/dist/packlets/context/convert/index.js +23 -0
- package/dist/packlets/context/index.js +26 -0
- package/dist/packlets/decisions/abstractDecision.js +68 -0
- package/dist/packlets/decisions/abstractDecisionCollector.js +90 -0
- package/dist/packlets/decisions/candidate.js +76 -0
- package/dist/packlets/decisions/common.js +23 -0
- package/dist/packlets/decisions/concreteDecision.js +111 -0
- package/dist/packlets/decisions/decision.js +126 -0
- package/dist/packlets/decisions/index.js +28 -0
- package/dist/packlets/import/fsItem.js +134 -0
- package/dist/packlets/import/importContext.js +129 -0
- package/dist/packlets/import/importManager.js +129 -0
- package/dist/packlets/import/importable.js +32 -0
- package/dist/packlets/import/importers/collectionImporter.js +118 -0
- package/dist/packlets/import/importers/fsItemImporter.js +116 -0
- package/dist/packlets/import/importers/importer.js +23 -0
- package/dist/packlets/import/importers/index.browser.js +29 -0
- package/dist/packlets/import/importers/index.js +27 -0
- package/dist/packlets/import/importers/jsonImporter.js +94 -0
- package/dist/packlets/import/importers/pathImporter.js +84 -0
- package/dist/packlets/import/index.browser.js +34 -0
- package/dist/packlets/import/index.js +28 -0
- package/dist/packlets/qualifier-types/config/convert.js +124 -0
- package/dist/packlets/qualifier-types/config/index.js +25 -0
- package/dist/packlets/qualifier-types/config/json.js +32 -0
- package/dist/packlets/qualifier-types/convert.js +56 -0
- package/dist/packlets/qualifier-types/helpers.js +82 -0
- package/dist/packlets/qualifier-types/index.js +32 -0
- package/dist/packlets/qualifier-types/languageQualifierType.js +142 -0
- package/dist/packlets/qualifier-types/literalQualifierType.js +200 -0
- package/dist/packlets/qualifier-types/literalValueHierarchy.js +236 -0
- package/dist/packlets/qualifier-types/qualifierType.js +184 -0
- package/dist/packlets/qualifier-types/qualifierTypeCollector.js +66 -0
- package/dist/packlets/qualifier-types/territoryQualifierType.js +200 -0
- package/dist/packlets/qualifiers/convert/decls.js +70 -0
- package/dist/packlets/qualifiers/convert/index.js +24 -0
- package/dist/packlets/qualifiers/convert/qualifier.js +40 -0
- package/dist/packlets/qualifiers/index.js +29 -0
- package/dist/packlets/qualifiers/qualifier.js +108 -0
- package/dist/packlets/qualifiers/qualifierCollector.js +123 -0
- package/dist/packlets/qualifiers/qualifierDecl.js +23 -0
- package/dist/packlets/qualifiers/qualifierDefaultValueDecls.js +23 -0
- package/dist/packlets/qualifiers/qualifierDefaultValueToken.js +175 -0
- package/dist/packlets/resource-json/compiled/common.js +23 -0
- package/dist/packlets/resource-json/compiled/convert.js +132 -0
- package/dist/packlets/resource-json/compiled/index.js +26 -0
- package/dist/packlets/resource-json/compiled/json.js +2 -0
- package/dist/packlets/resource-json/convert.js +171 -0
- package/dist/packlets/resource-json/helpers.js +241 -0
- package/dist/packlets/resource-json/index.js +31 -0
- package/dist/packlets/resource-json/json.js +36 -0
- package/dist/packlets/resource-json/normalized.js +23 -0
- package/dist/packlets/resource-json/resourceDeclCollection.js +88 -0
- package/dist/packlets/resource-json/resourceDeclContainer.js +23 -0
- package/dist/packlets/resource-json/resourceDeclTree.js +94 -0
- package/dist/packlets/resource-types/config/convert.js +35 -0
- package/dist/packlets/resource-types/config/index.js +25 -0
- package/dist/packlets/resource-types/config/json.js +23 -0
- package/dist/packlets/resource-types/helpers.js +42 -0
- package/dist/packlets/resource-types/index.js +28 -0
- package/dist/packlets/resource-types/jsonResourceType.js +66 -0
- package/dist/packlets/resource-types/resourceType.js +95 -0
- package/dist/packlets/resource-types/resourceTypeCollector.js +61 -0
- package/dist/packlets/resources/candidateReducer.js +246 -0
- package/dist/packlets/resources/candidateValue.js +92 -0
- package/dist/packlets/resources/candidateValueCollector.js +94 -0
- package/dist/packlets/resources/common.js +23 -0
- package/dist/packlets/resources/deltaGenerator.js +338 -0
- package/dist/packlets/resources/index.js +31 -0
- package/dist/packlets/resources/resource.js +207 -0
- package/dist/packlets/resources/resourceBuilder.js +183 -0
- package/dist/packlets/resources/resourceCandidate.js +216 -0
- package/dist/packlets/resources/resourceManagerBuilder.js +890 -0
- package/dist/packlets/runtime/cacheListener.js +58 -0
- package/dist/packlets/runtime/cacheMetrics.js +149 -0
- package/dist/packlets/runtime/compiledResourceCollection.js +473 -0
- package/dist/packlets/runtime/conditionSetResolutionResult.js +134 -0
- package/dist/packlets/runtime/context/contextQualifierProvider.js +29 -0
- package/dist/packlets/runtime/context/contextQualifierProviderValidator.js +146 -0
- package/dist/packlets/runtime/context/index.js +26 -0
- package/dist/packlets/runtime/context/simpleContextQualifierProvider.js +196 -0
- package/dist/packlets/runtime/context/validatingSimpleContextQualifierProvider.js +60 -0
- package/dist/packlets/runtime/iResourceManager.js +23 -0
- package/dist/packlets/runtime/index.js +34 -0
- package/dist/packlets/runtime/resource-tree/common.js +23 -0
- package/dist/packlets/runtime/resource-tree/index.js +26 -0
- package/dist/packlets/runtime/resource-tree/readOnlyResourceTree.js +216 -0
- package/dist/packlets/runtime/resource-tree/resourceTreeChildren.js +97 -0
- package/dist/packlets/runtime/resource-tree/resourceTreeChildrenValidator.js +161 -0
- package/dist/packlets/runtime/resourceResolver.js +481 -0
- package/dist/packlets/runtime/resourceTreeResolver.js +220 -0
- package/dist/packlets/runtime/validate.js +47 -0
- package/dist/packlets/zip-archive/convert.js +100 -0
- package/dist/packlets/zip-archive/index.browser.js +54 -0
- package/dist/packlets/zip-archive/index.js +47 -0
- package/dist/packlets/zip-archive/json.js +23 -0
- package/dist/packlets/zip-archive/types.js +36 -0
- package/dist/packlets/zip-archive/zipArchiveCreator.js +191 -0
- package/dist/packlets/zip-archive/zipArchiveFormat.js +140 -0
- package/dist/packlets/zip-archive/zipArchiveLoader.js +282 -0
- package/dist/test/data/sample.json +32 -0
- package/dist/test/unit/qualifier-types/testQualifierType.js +76 -0
- package/dist/test/unit/resource-types/testDerivedResourceType.js +109 -0
- package/dist/test/unit/resources/deltaGenerator.helpers.js +282 -0
- package/dist/tsdoc-metadata.json +1 -1
- package/lib/index.browser.d.ts +24 -0
- package/lib/index.browser.js +116 -0
- package/lib/packlets/config/index.browser.d.ts +7 -0
- package/lib/packlets/config/index.browser.js +74 -0
- package/lib/packlets/import/importers/index.browser.d.ts +4 -0
- package/lib/packlets/import/importers/index.browser.js +45 -0
- package/lib/packlets/import/index.browser.d.ts +7 -0
- package/lib/packlets/import/index.browser.js +74 -0
- package/lib/packlets/zip-archive/index.browser.d.ts +27 -0
- package/lib/packlets/zip-archive/index.browser.js +102 -0
- package/package.json +21 -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
|