@fgv/ts-res-cli 1.0.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.
- package/.eslintrc.js +9 -0
- package/.rush/temp/chunked-rush-logs/ts-res-cli.build.chunks.jsonl +6 -0
- package/.rush/temp/operation/build/log-chunks.jsonl +6 -0
- package/.rush/temp/operation/build/state.json +3 -0
- package/.rush/temp/shrinkwrap-deps.json +651 -0
- package/README.md +197 -0
- package/bin/ts-res-compile.js +40 -0
- package/config/jest.config.json +9 -0
- package/config/rig.json +16 -0
- package/lib/cli.d.ts +36 -0
- package/lib/cli.d.ts.map +1 -0
- package/lib/cli.js +464 -0
- package/lib/cli.js.map +1 -0
- package/lib/compiler.d.ts +86 -0
- package/lib/compiler.d.ts.map +1 -0
- package/lib/compiler.js +415 -0
- package/lib/compiler.js.map +1 -0
- package/lib/defaultConfiguration.d.ts +7 -0
- package/lib/defaultConfiguration.d.ts.map +1 -0
- package/lib/defaultConfiguration.js +79 -0
- package/lib/defaultConfiguration.js.map +1 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +41 -0
- package/lib/index.js.map +1 -0
- package/lib/options.d.ts +66 -0
- package/lib/options.d.ts.map +1 -0
- package/lib/options.js +24 -0
- package/lib/options.js.map +1 -0
- package/package.json +59 -0
- package/src/cli.ts +607 -0
- package/src/compiler.ts +504 -0
- package/src/defaultConfiguration.ts +78 -0
- package/src/index.ts +25 -0
- package/src/options.ts +101 -0
- package/test/data/resource-collection.json +28 -0
- package/test/data/sample-resources.json +41 -0
- package/test/integration/cli-configuration.test.ts +419 -0
- package/test/integration/cli-context-filter-working.test.ts +341 -0
- package/test/integration/cli-integration.test.ts +533 -0
- package/test/unit/cli.test.ts +413 -0
- package/test/unit/compiler.test.ts +1084 -0
- package/tsconfig.json +8 -0
package/lib/compiler.js
ADDED
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025 Erik Fortune
|
|
4
|
+
*
|
|
5
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
* in the Software without restriction, including without limitation the rights
|
|
8
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
* furnished to do so, subject to the following conditions:
|
|
11
|
+
*
|
|
12
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
* copies or substantial portions of the Software.
|
|
14
|
+
*
|
|
15
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
* SOFTWARE.
|
|
22
|
+
*/
|
|
23
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
26
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
27
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
28
|
+
}
|
|
29
|
+
Object.defineProperty(o, k2, desc);
|
|
30
|
+
}) : (function(o, m, k, k2) {
|
|
31
|
+
if (k2 === undefined) k2 = k;
|
|
32
|
+
o[k2] = m[k];
|
|
33
|
+
}));
|
|
34
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
35
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
36
|
+
}) : function(o, v) {
|
|
37
|
+
o["default"] = v;
|
|
38
|
+
});
|
|
39
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
40
|
+
var ownKeys = function(o) {
|
|
41
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
42
|
+
var ar = [];
|
|
43
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
44
|
+
return ar;
|
|
45
|
+
};
|
|
46
|
+
return ownKeys(o);
|
|
47
|
+
};
|
|
48
|
+
return function (mod) {
|
|
49
|
+
if (mod && mod.__esModule) return mod;
|
|
50
|
+
var result = {};
|
|
51
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
52
|
+
__setModuleDefault(result, mod);
|
|
53
|
+
return result;
|
|
54
|
+
};
|
|
55
|
+
})();
|
|
56
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
57
|
+
exports.ResourceCompiler = void 0;
|
|
58
|
+
const ts_utils_1 = require("@fgv/ts-utils");
|
|
59
|
+
const TsRes = __importStar(require("@fgv/ts-res"));
|
|
60
|
+
const defaultConfiguration_1 = require("./defaultConfiguration");
|
|
61
|
+
const fs_1 = require("fs");
|
|
62
|
+
const path = __importStar(require("path"));
|
|
63
|
+
/**
|
|
64
|
+
* Main resource compiler class
|
|
65
|
+
*/
|
|
66
|
+
class ResourceCompiler {
|
|
67
|
+
constructor(options) {
|
|
68
|
+
this._options = options;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Compiles resources according to the configured options
|
|
72
|
+
*/
|
|
73
|
+
async compile() {
|
|
74
|
+
try {
|
|
75
|
+
if (this._options.debug) {
|
|
76
|
+
console.error('Starting resource compilation...');
|
|
77
|
+
console.error('Options:', JSON.stringify(this._options, null, 2));
|
|
78
|
+
}
|
|
79
|
+
// Load and validate configuration
|
|
80
|
+
const config = (await this._loadConfiguration()).orThrow((err) => `Failed to load configuration: ${err}`);
|
|
81
|
+
if (this._options.debug) {
|
|
82
|
+
console.error('Configuration loaded successfully');
|
|
83
|
+
}
|
|
84
|
+
// Load resources from input
|
|
85
|
+
const original = (await this._loadResources(config)).orThrow((err) => `Failed to load resources: ${err}`);
|
|
86
|
+
if (this._options.verbose) {
|
|
87
|
+
console.error(`Loaded ${original.numResources} resources with ${original.numCandidates} candidates`);
|
|
88
|
+
}
|
|
89
|
+
// Apply context filtering if specified
|
|
90
|
+
const filtered = this._applyFilters(original).orThrow((err) => `Failed to apply context filtering: ${err}`);
|
|
91
|
+
if (this._options.verbose && filtered.manager !== filtered.original) {
|
|
92
|
+
console.error(`After context filtering: ${filtered.manager.numResources} resources, ${filtered.manager.numCandidates} candidates`);
|
|
93
|
+
}
|
|
94
|
+
// Generate output blob
|
|
95
|
+
const blob = (await this._generateBlob(filtered)).orThrow((err) => `Failed to generate output blob: ${err}`);
|
|
96
|
+
if (this._options.debug) {
|
|
97
|
+
console.error(`Generated ${this._options.format} format output blob`);
|
|
98
|
+
}
|
|
99
|
+
// Write output
|
|
100
|
+
(await this._writeOutput(blob)).orThrow((err) => `Failed to write output: ${err}`);
|
|
101
|
+
if (this._options.debug) {
|
|
102
|
+
console.error(`Output written to: ${this._options.output}`);
|
|
103
|
+
}
|
|
104
|
+
return (0, ts_utils_1.succeed)(blob);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
return (0, ts_utils_1.fail)(`Compilation failed: ${error}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Validates resources without compilation
|
|
112
|
+
*/
|
|
113
|
+
async validate() {
|
|
114
|
+
try {
|
|
115
|
+
// Load and validate configuration
|
|
116
|
+
const config = (await this._loadConfiguration()).orThrow((err) => `Failed to load configuration: ${err}`);
|
|
117
|
+
const manager = (await this._loadResources(config)).orThrow((err) => `Failed to load resources: ${err}`);
|
|
118
|
+
const filtered = this._applyFilters(manager).orThrow((err) => `Failed to apply context filtering: ${err}`);
|
|
119
|
+
// Build all resources to trigger validation
|
|
120
|
+
return filtered.manager.build().onSuccess((manager) => {
|
|
121
|
+
if (this._options.verbose) {
|
|
122
|
+
console.error(`Resource validation successful with ${manager.numResources} resources and ${manager.numCandidates} candidates`);
|
|
123
|
+
}
|
|
124
|
+
return (0, ts_utils_1.succeed)(manager);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
return (0, ts_utils_1.fail)(`Validation failed: ${error}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Gets information about the resources
|
|
133
|
+
*/
|
|
134
|
+
async getInfo() {
|
|
135
|
+
try {
|
|
136
|
+
// Load and validate configuration
|
|
137
|
+
const config = (await this._loadConfiguration()).orThrow((err) => `Failed to load configuration: ${err}`);
|
|
138
|
+
const manager = (await this._loadResources(config)).orThrow((err) => `Failed to load resources: ${err}`);
|
|
139
|
+
const filtered = this._applyFilters(manager).orThrow((err) => `Failed to apply context filtering: ${err}`);
|
|
140
|
+
return (0, ts_utils_1.succeed)(this._generateResourceInfo(filtered));
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
return (0, ts_utils_1.fail)(`Failed to get resource info: ${error}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Loads and validates the system configuration
|
|
148
|
+
*/
|
|
149
|
+
async _loadConfiguration() {
|
|
150
|
+
try {
|
|
151
|
+
if (this._options.config) {
|
|
152
|
+
// Check if it's a predefined configuration name
|
|
153
|
+
const predefinedNames = [
|
|
154
|
+
'default',
|
|
155
|
+
'language-priority',
|
|
156
|
+
'territory-priority',
|
|
157
|
+
'extended-example'
|
|
158
|
+
];
|
|
159
|
+
if (predefinedNames.includes(this._options.config)) {
|
|
160
|
+
const predefinedResult = TsRes.Config.getPredefinedDeclaration(this._options.config);
|
|
161
|
+
if (predefinedResult.isSuccess()) {
|
|
162
|
+
this._systemConfiguration = predefinedResult.value;
|
|
163
|
+
if (this._options.verbose) {
|
|
164
|
+
console.error(`Using predefined configuration: ${this._systemConfiguration.name}`);
|
|
165
|
+
}
|
|
166
|
+
return (0, ts_utils_1.succeed)(this._systemConfiguration);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// If not a predefined config, try to load as file path
|
|
170
|
+
try {
|
|
171
|
+
const configPath = path.resolve(this._options.config);
|
|
172
|
+
if (this._options.debug) {
|
|
173
|
+
console.error(`Loading configuration from: ${configPath}`);
|
|
174
|
+
}
|
|
175
|
+
const configContent = await fs_1.promises.readFile(configPath, 'utf-8');
|
|
176
|
+
const configData = JSON.parse(configContent);
|
|
177
|
+
// Validate the configuration using ts-res converter
|
|
178
|
+
const configResult = TsRes.Config.Convert.systemConfiguration.convert(configData);
|
|
179
|
+
if (configResult.isFailure()) {
|
|
180
|
+
return (0, ts_utils_1.fail)(`Invalid configuration file: ${configResult.message}`);
|
|
181
|
+
}
|
|
182
|
+
this._systemConfiguration = configResult.value;
|
|
183
|
+
if (this._options.verbose) {
|
|
184
|
+
console.error(`Using custom configuration: ${this._systemConfiguration.name}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
catch (fileError) {
|
|
188
|
+
return (0, ts_utils_1.fail)(`Configuration '${this._options.config}' is not a predefined configuration name and failed to load as file: ${fileError}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
// Use default predefined configuration
|
|
193
|
+
const defaultResult = TsRes.Config.getPredefinedDeclaration('default');
|
|
194
|
+
if (defaultResult.isSuccess()) {
|
|
195
|
+
this._systemConfiguration = defaultResult.value;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
// Fallback to hardcoded default if predefined default is not available
|
|
199
|
+
this._systemConfiguration = defaultConfiguration_1.DEFAULT_SYSTEM_CONFIGURATION;
|
|
200
|
+
}
|
|
201
|
+
if (this._options.verbose) {
|
|
202
|
+
console.error(`Using default configuration: ${this._systemConfiguration.name}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return (0, ts_utils_1.succeed)(this._systemConfiguration);
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
return (0, ts_utils_1.fail)(`Failed to load configuration: ${error}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Loads resources from the input path using the configured system
|
|
213
|
+
*/
|
|
214
|
+
async _loadResources(config) {
|
|
215
|
+
try {
|
|
216
|
+
if (!this._systemConfiguration) {
|
|
217
|
+
return (0, ts_utils_1.fail)('System configuration not loaded');
|
|
218
|
+
}
|
|
219
|
+
// Parse qualifier defaults if provided
|
|
220
|
+
let qualifierDefaultValues;
|
|
221
|
+
if (this._options.qualifierDefaults) {
|
|
222
|
+
// We need to create a temporary system configuration first to parse defaults
|
|
223
|
+
const tempSystemConfigResult = TsRes.Config.SystemConfiguration.create(this._systemConfiguration);
|
|
224
|
+
if (tempSystemConfigResult.isFailure()) {
|
|
225
|
+
return (0, ts_utils_1.fail)(`Failed to create temporary system configuration: ${tempSystemConfigResult.message}`);
|
|
226
|
+
}
|
|
227
|
+
const tokens = new TsRes.Qualifiers.QualifierDefaultValueTokens(tempSystemConfigResult.value.qualifiers);
|
|
228
|
+
const defaultsResult = tokens.qualifierDefaultValuesTokenToDecl(this._options.qualifierDefaults);
|
|
229
|
+
if (defaultsResult.isFailure()) {
|
|
230
|
+
return (0, ts_utils_1.fail)(`Failed to parse qualifier defaults: ${defaultsResult.message}`);
|
|
231
|
+
}
|
|
232
|
+
qualifierDefaultValues = defaultsResult.value;
|
|
233
|
+
}
|
|
234
|
+
// Create system configuration and ts-res system
|
|
235
|
+
const systemConfigResult = TsRes.Config.SystemConfiguration.create(this._systemConfiguration, qualifierDefaultValues ? { qualifierDefaultValues } : undefined);
|
|
236
|
+
if (systemConfigResult.isFailure()) {
|
|
237
|
+
return (0, ts_utils_1.fail)(`Failed to create system configuration: ${systemConfigResult.message}`);
|
|
238
|
+
}
|
|
239
|
+
const systemConfig = systemConfigResult.value;
|
|
240
|
+
// Create resource manager from system configuration
|
|
241
|
+
const manager = TsRes.Resources.ResourceManagerBuilder.create({
|
|
242
|
+
qualifiers: systemConfig.qualifiers,
|
|
243
|
+
resourceTypes: systemConfig.resourceTypes
|
|
244
|
+
});
|
|
245
|
+
if (manager.isFailure()) {
|
|
246
|
+
return (0, ts_utils_1.fail)(`Failed to create resource manager: ${manager.message}`);
|
|
247
|
+
}
|
|
248
|
+
// Load resources from input path
|
|
249
|
+
const importResult = await this._importResources(manager.value);
|
|
250
|
+
if (importResult.isFailure()) {
|
|
251
|
+
return (0, ts_utils_1.fail)(`Failed to import resources: ${importResult.message}`);
|
|
252
|
+
}
|
|
253
|
+
return (0, ts_utils_1.succeed)(manager.value);
|
|
254
|
+
}
|
|
255
|
+
catch (error) {
|
|
256
|
+
return (0, ts_utils_1.fail)(`Failed to load resources: ${error}`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Imports resources from the input path using ImportManager
|
|
261
|
+
*/
|
|
262
|
+
async _importResources(manager) {
|
|
263
|
+
try {
|
|
264
|
+
const inputPath = path.resolve(this._options.input);
|
|
265
|
+
// Create FileTree for file system operations
|
|
266
|
+
const fileTree = ts_utils_1.FileTree.forFilesystem();
|
|
267
|
+
if (fileTree.isFailure()) {
|
|
268
|
+
return (0, ts_utils_1.fail)(`Failed to create file tree: ${fileTree.message}`);
|
|
269
|
+
}
|
|
270
|
+
// Create ImportManager with the resource manager and file tree
|
|
271
|
+
const importManager = TsRes.Import.ImportManager.create({
|
|
272
|
+
resources: manager,
|
|
273
|
+
fileTree: fileTree.value
|
|
274
|
+
});
|
|
275
|
+
if (importManager.isFailure()) {
|
|
276
|
+
return (0, ts_utils_1.fail)(`Failed to create import manager: ${importManager.message}`);
|
|
277
|
+
}
|
|
278
|
+
// Use ImportManager to handle both files and directories automatically
|
|
279
|
+
if (this._options.debug) {
|
|
280
|
+
console.error(`Importing resources from: ${inputPath}`);
|
|
281
|
+
}
|
|
282
|
+
const importResult = importManager.value.importFromFileSystem(inputPath);
|
|
283
|
+
if (importResult.isFailure()) {
|
|
284
|
+
return (0, ts_utils_1.fail)(`Failed to import from ${inputPath}: ${importResult.message}`);
|
|
285
|
+
}
|
|
286
|
+
if (this._options.verbose) {
|
|
287
|
+
console.error(`Successfully imported resources from: ${inputPath}`);
|
|
288
|
+
}
|
|
289
|
+
return (0, ts_utils_1.succeed)(undefined);
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
return (0, ts_utils_1.fail)(`Failed to import resources: ${error}`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Applies filters to imported resources
|
|
297
|
+
*/
|
|
298
|
+
_applyFilters(original) {
|
|
299
|
+
if (this._options.contextFilter) {
|
|
300
|
+
const tokens = new TsRes.Context.ContextTokens(original.qualifiers);
|
|
301
|
+
return tokens.contextTokenToPartialContext(this._options.contextFilter).onSuccess((context) => {
|
|
302
|
+
return original
|
|
303
|
+
.clone({
|
|
304
|
+
filterForContext: context,
|
|
305
|
+
reduceQualifiers: this._options.reduceQualifiers
|
|
306
|
+
})
|
|
307
|
+
.onSuccess((manager) => {
|
|
308
|
+
return (0, ts_utils_1.succeed)({ original, manager, context });
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
return (0, ts_utils_1.succeed)({ original, manager: original });
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Generates the output blob
|
|
316
|
+
*/
|
|
317
|
+
async _generateBlob(filtered) {
|
|
318
|
+
try {
|
|
319
|
+
if (this._options.format === 'compiled') {
|
|
320
|
+
return this._generateCompiledBlob(filtered);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
return this._generateSourceBlob(filtered);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
catch (error) {
|
|
327
|
+
return (0, ts_utils_1.fail)(`Failed to generate blob: ${error}`);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Generates a compiled resource collection blob
|
|
332
|
+
*/
|
|
333
|
+
_generateCompiledBlob(filtered) {
|
|
334
|
+
// Build all resources to ensure they're ready for compilation
|
|
335
|
+
return filtered.manager.getCompiledResourceCollection().onSuccess((compiled) => {
|
|
336
|
+
const blob = {
|
|
337
|
+
compiledCollection: compiled
|
|
338
|
+
};
|
|
339
|
+
if (this._options.includeMetadata) {
|
|
340
|
+
blob.metadata = this._generateResourceInfo(filtered);
|
|
341
|
+
}
|
|
342
|
+
return (0, ts_utils_1.succeed)(blob);
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Generates a source format blob (legacy format)
|
|
347
|
+
*/
|
|
348
|
+
_generateSourceBlob(filtered) {
|
|
349
|
+
return filtered.manager.getResourceCollectionDecl().onSuccess((resources) => {
|
|
350
|
+
const blob = { resources };
|
|
351
|
+
if (this._options.includeMetadata) {
|
|
352
|
+
blob.metadata = this._generateResourceInfo(filtered);
|
|
353
|
+
}
|
|
354
|
+
return (0, ts_utils_1.succeed)(blob);
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Generates resource information
|
|
359
|
+
*/
|
|
360
|
+
_generateResourceInfo(filtered) {
|
|
361
|
+
const resourceTypes = Array.from(new Set(filtered.manager
|
|
362
|
+
.getAllCandidates()
|
|
363
|
+
.map((c) => { var _a; return (_a = c.resourceType) === null || _a === void 0 ? void 0 : _a.key; })
|
|
364
|
+
.filter(Boolean)));
|
|
365
|
+
const qualifiers = Array.from(filtered.manager.qualifiers.keys());
|
|
366
|
+
const info = Object.assign({ totalResources: filtered.original.numResources, totalCandidates: filtered.original.numCandidates, filteredResources: filtered.manager.numResources, filteredCandidates: filtered.manager.numCandidates, resourceTypes,
|
|
367
|
+
qualifiers }, (filtered.context ? { context: filtered.context } : undefined));
|
|
368
|
+
return info;
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Writes the output blob to the specified output path
|
|
372
|
+
*/
|
|
373
|
+
async _writeOutput(blob) {
|
|
374
|
+
try {
|
|
375
|
+
const outputPath = path.resolve(this._options.output);
|
|
376
|
+
const outputDir = path.dirname(outputPath);
|
|
377
|
+
// Ensure output directory exists
|
|
378
|
+
await fs_1.promises.mkdir(outputDir, { recursive: true });
|
|
379
|
+
let content;
|
|
380
|
+
switch (this._options.format) {
|
|
381
|
+
case 'compiled':
|
|
382
|
+
// If metadata is included, write the full blob; otherwise, write just the compiled collection
|
|
383
|
+
const compiledData = this._options.includeMetadata ? blob : blob.compiledCollection;
|
|
384
|
+
content = JSON.stringify(compiledData, null, 2);
|
|
385
|
+
break;
|
|
386
|
+
case 'source':
|
|
387
|
+
content = JSON.stringify(blob, null, 2);
|
|
388
|
+
break;
|
|
389
|
+
case 'js':
|
|
390
|
+
const jsData = blob.compiledCollection || blob;
|
|
391
|
+
content = `module.exports = ${JSON.stringify(jsData, null, 2)};`;
|
|
392
|
+
break;
|
|
393
|
+
case 'ts':
|
|
394
|
+
const tsData = blob.compiledCollection || blob;
|
|
395
|
+
content = `export const resources = ${JSON.stringify(tsData, null, 2)} as const;`;
|
|
396
|
+
break;
|
|
397
|
+
case 'binary':
|
|
398
|
+
// For binary format, we could use a more efficient serialization
|
|
399
|
+
// For now, use JSON as a placeholder
|
|
400
|
+
const binaryData = blob.compiledCollection || blob;
|
|
401
|
+
content = JSON.stringify(binaryData);
|
|
402
|
+
break;
|
|
403
|
+
default:
|
|
404
|
+
return (0, ts_utils_1.fail)(`Unsupported output format: ${this._options.format}`);
|
|
405
|
+
}
|
|
406
|
+
await fs_1.promises.writeFile(outputPath, content, 'utf-8');
|
|
407
|
+
return (0, ts_utils_1.succeed)(undefined);
|
|
408
|
+
}
|
|
409
|
+
catch (error) {
|
|
410
|
+
return (0, ts_utils_1.fail)(`Failed to write output: ${error}`);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
exports.ResourceCompiler = ResourceCompiler;
|
|
415
|
+
//# sourceMappingURL=compiler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compiler.js","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"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","sourcesContent":["/*\r\n * Copyright (c) 2025 Erik Fortune\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to deal\r\n * in the Software without restriction, including without limitation the rights\r\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n * copies of the Software, and to permit persons to whom the Software is\r\n * furnished to do so, subject to the following conditions:\r\n *\r\n * The above copyright notice and this permission notice shall be included in all\r\n * copies or substantial portions of the Software.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n * SOFTWARE.\r\n */\r\n\r\nimport { Result, succeed, fail, FileTree } from '@fgv/ts-utils';\r\nimport { JsonObject } from '@fgv/ts-json-base';\r\nimport * as TsRes from '@fgv/ts-res';\r\nimport { ICompileOptions } from './options';\r\nimport { DEFAULT_SYSTEM_CONFIGURATION } from './defaultConfiguration';\r\nimport { promises as fs } from 'fs';\r\nimport * as path from 'path';\r\n\r\n/**\r\n * Information about compiled resources\r\n */\r\nexport interface IResourceInfo {\r\n totalResources: number;\r\n totalCandidates: number;\r\n filteredResources: number;\r\n filteredCandidates: number;\r\n resourceTypes: string[];\r\n qualifiers: string[];\r\n context?: JsonObject;\r\n}\r\n\r\nexport interface IFilteredManager {\r\n original: TsRes.Resources.ResourceManagerBuilder;\r\n manager: TsRes.Resources.ResourceManagerBuilder;\r\n context?: JsonObject;\r\n}\r\n\r\n/**\r\n * Compiled resource blob\r\n */\r\nexport interface IResourceBlob {\r\n resources?: TsRes.ResourceJson.Json.IResourceCollectionDecl;\r\n compiledCollection?: TsRes.ResourceJson.Compiled.ICompiledResourceCollection;\r\n metadata?: IResourceInfo;\r\n}\r\n\r\n/**\r\n * Main resource compiler class\r\n */\r\nexport class ResourceCompiler {\r\n private readonly _options: ICompileOptions;\r\n private _systemConfiguration?: TsRes.Config.Model.ISystemConfiguration;\r\n\r\n public constructor(options: ICompileOptions) {\r\n this._options = options;\r\n }\r\n\r\n /**\r\n * Compiles resources according to the configured options\r\n */\r\n public async compile(): Promise<Result<IResourceBlob>> {\r\n try {\r\n if (this._options.debug) {\r\n console.error('Starting resource compilation...');\r\n console.error('Options:', JSON.stringify(this._options, null, 2));\r\n }\r\n\r\n // Load and validate configuration\r\n const config = (await this._loadConfiguration()).orThrow(\r\n (err) => `Failed to load configuration: ${err}`\r\n );\r\n\r\n if (this._options.debug) {\r\n console.error('Configuration loaded successfully');\r\n }\r\n\r\n // Load resources from input\r\n const original = (await this._loadResources(config)).orThrow(\r\n (err) => `Failed to load resources: ${err}`\r\n );\r\n\r\n if (this._options.verbose) {\r\n console.error(`Loaded ${original.numResources} resources with ${original.numCandidates} candidates`);\r\n }\r\n\r\n // Apply context filtering if specified\r\n const filtered = this._applyFilters(original).orThrow(\r\n (err) => `Failed to apply context filtering: ${err}`\r\n );\r\n\r\n if (this._options.verbose && filtered.manager !== filtered.original) {\r\n console.error(\r\n `After context filtering: ${filtered.manager.numResources} resources, ${filtered.manager.numCandidates} candidates`\r\n );\r\n }\r\n\r\n // Generate output blob\r\n const blob = (await this._generateBlob(filtered)).orThrow(\r\n (err) => `Failed to generate output blob: ${err}`\r\n );\r\n\r\n if (this._options.debug) {\r\n console.error(`Generated ${this._options.format} format output blob`);\r\n }\r\n\r\n // Write output\r\n (await this._writeOutput(blob)).orThrow((err) => `Failed to write output: ${err}`);\r\n\r\n if (this._options.debug) {\r\n console.error(`Output written to: ${this._options.output}`);\r\n }\r\n\r\n return succeed(blob);\r\n } catch (error) {\r\n return fail(`Compilation failed: ${error}`);\r\n }\r\n }\r\n\r\n /**\r\n * Validates resources without compilation\r\n */\r\n public async validate(): Promise<Result<TsRes.Resources.ResourceManagerBuilder>> {\r\n try {\r\n // Load and validate configuration\r\n const config = (await this._loadConfiguration()).orThrow(\r\n (err) => `Failed to load configuration: ${err}`\r\n );\r\n\r\n const manager = (await this._loadResources(config)).orThrow(\r\n (err) => `Failed to load resources: ${err}`\r\n );\r\n\r\n const filtered = this._applyFilters(manager).orThrow(\r\n (err) => `Failed to apply context filtering: ${err}`\r\n );\r\n\r\n // Build all resources to trigger validation\r\n return filtered.manager.build().onSuccess((manager) => {\r\n if (this._options.verbose) {\r\n console.error(\r\n `Resource validation successful with ${manager.numResources} resources and ${manager.numCandidates} candidates`\r\n );\r\n }\r\n return succeed(manager);\r\n });\r\n } catch (error) {\r\n return fail(`Validation failed: ${error}`);\r\n }\r\n }\r\n\r\n /**\r\n * Gets information about the resources\r\n */\r\n public async getInfo(): Promise<Result<IResourceInfo>> {\r\n try {\r\n // Load and validate configuration\r\n const config = (await this._loadConfiguration()).orThrow(\r\n (err) => `Failed to load configuration: ${err}`\r\n );\r\n\r\n const manager = (await this._loadResources(config)).orThrow(\r\n (err) => `Failed to load resources: ${err}`\r\n );\r\n\r\n const filtered = this._applyFilters(manager).orThrow(\r\n (err) => `Failed to apply context filtering: ${err}`\r\n );\r\n\r\n return succeed(this._generateResourceInfo(filtered));\r\n } catch (error) {\r\n return fail(`Failed to get resource info: ${error}`);\r\n }\r\n }\r\n\r\n /**\r\n * Loads and validates the system configuration\r\n */\r\n private async _loadConfiguration(): Promise<Result<TsRes.Config.Model.ISystemConfiguration>> {\r\n try {\r\n if (this._options.config) {\r\n // Check if it's a predefined configuration name\r\n const predefinedNames: TsRes.Config.PredefinedSystemConfiguration[] = [\r\n 'default',\r\n 'language-priority',\r\n 'territory-priority',\r\n 'extended-example'\r\n ];\r\n if (predefinedNames.includes(this._options.config as TsRes.Config.PredefinedSystemConfiguration)) {\r\n const predefinedResult = TsRes.Config.getPredefinedDeclaration(\r\n this._options.config as TsRes.Config.PredefinedSystemConfiguration\r\n );\r\n if (predefinedResult.isSuccess()) {\r\n this._systemConfiguration = predefinedResult.value;\r\n if (this._options.verbose) {\r\n console.error(`Using predefined configuration: ${this._systemConfiguration.name}`);\r\n }\r\n return succeed(this._systemConfiguration);\r\n }\r\n }\r\n\r\n // If not a predefined config, try to load as file path\r\n try {\r\n const configPath = path.resolve(this._options.config);\r\n if (this._options.debug) {\r\n console.error(`Loading configuration from: ${configPath}`);\r\n }\r\n const configContent = await fs.readFile(configPath, 'utf-8');\r\n const configData = JSON.parse(configContent);\r\n\r\n // Validate the configuration using ts-res converter\r\n const configResult = TsRes.Config.Convert.systemConfiguration.convert(configData);\r\n if (configResult.isFailure()) {\r\n return fail(`Invalid configuration file: ${configResult.message}`);\r\n }\r\n\r\n this._systemConfiguration = configResult.value;\r\n if (this._options.verbose) {\r\n console.error(`Using custom configuration: ${this._systemConfiguration.name}`);\r\n }\r\n } catch (fileError) {\r\n return fail(\r\n `Configuration '${this._options.config}' is not a predefined configuration name and failed to load as file: ${fileError}`\r\n );\r\n }\r\n } else {\r\n // Use default predefined configuration\r\n const defaultResult = TsRes.Config.getPredefinedDeclaration('default');\r\n if (defaultResult.isSuccess()) {\r\n this._systemConfiguration = defaultResult.value;\r\n } else {\r\n // Fallback to hardcoded default if predefined default is not available\r\n this._systemConfiguration = DEFAULT_SYSTEM_CONFIGURATION;\r\n }\r\n if (this._options.verbose) {\r\n console.error(`Using default configuration: ${this._systemConfiguration.name}`);\r\n }\r\n }\r\n\r\n return succeed(this._systemConfiguration);\r\n } catch (error) {\r\n return fail(`Failed to load configuration: ${error}`);\r\n }\r\n }\r\n\r\n /**\r\n * Loads resources from the input path using the configured system\r\n */\r\n private async _loadResources(\r\n config: TsRes.Config.Model.ISystemConfiguration\r\n ): Promise<Result<TsRes.Resources.ResourceManagerBuilder>> {\r\n try {\r\n if (!this._systemConfiguration) {\r\n return fail('System configuration not loaded');\r\n }\r\n\r\n // Parse qualifier defaults if provided\r\n let qualifierDefaultValues: Record<string, string | null> | undefined;\r\n if (this._options.qualifierDefaults) {\r\n // We need to create a temporary system configuration first to parse defaults\r\n const tempSystemConfigResult = TsRes.Config.SystemConfiguration.create(this._systemConfiguration);\r\n if (tempSystemConfigResult.isFailure()) {\r\n return fail(`Failed to create temporary system configuration: ${tempSystemConfigResult.message}`);\r\n }\r\n\r\n const tokens = new TsRes.Qualifiers.QualifierDefaultValueTokens(\r\n tempSystemConfigResult.value.qualifiers\r\n );\r\n const defaultsResult = tokens.qualifierDefaultValuesTokenToDecl(this._options.qualifierDefaults);\r\n if (defaultsResult.isFailure()) {\r\n return fail(`Failed to parse qualifier defaults: ${defaultsResult.message}`);\r\n }\r\n\r\n qualifierDefaultValues = defaultsResult.value;\r\n }\r\n\r\n // Create system configuration and ts-res system\r\n const systemConfigResult = TsRes.Config.SystemConfiguration.create(\r\n this._systemConfiguration,\r\n qualifierDefaultValues ? { qualifierDefaultValues } : undefined\r\n );\r\n if (systemConfigResult.isFailure()) {\r\n return fail(`Failed to create system configuration: ${systemConfigResult.message}`);\r\n }\r\n\r\n const systemConfig = systemConfigResult.value;\r\n\r\n // Create resource manager from system configuration\r\n const manager = TsRes.Resources.ResourceManagerBuilder.create({\r\n qualifiers: systemConfig.qualifiers,\r\n resourceTypes: systemConfig.resourceTypes\r\n });\r\n\r\n if (manager.isFailure()) {\r\n return fail(`Failed to create resource manager: ${manager.message}`);\r\n }\r\n\r\n // Load resources from input path\r\n const importResult = await this._importResources(manager.value);\r\n if (importResult.isFailure()) {\r\n return fail(`Failed to import resources: ${importResult.message}`);\r\n }\r\n\r\n return succeed(manager.value);\r\n } catch (error) {\r\n return fail(`Failed to load resources: ${error}`);\r\n }\r\n }\r\n\r\n /**\r\n * Imports resources from the input path using ImportManager\r\n */\r\n private async _importResources(manager: TsRes.Resources.ResourceManagerBuilder): Promise<Result<void>> {\r\n try {\r\n const inputPath = path.resolve(this._options.input);\r\n\r\n // Create FileTree for file system operations\r\n const fileTree = FileTree.forFilesystem();\r\n if (fileTree.isFailure()) {\r\n return fail(`Failed to create file tree: ${fileTree.message}`);\r\n }\r\n\r\n // Create ImportManager with the resource manager and file tree\r\n const importManager = TsRes.Import.ImportManager.create({\r\n resources: manager,\r\n fileTree: fileTree.value\r\n });\r\n\r\n if (importManager.isFailure()) {\r\n return fail(`Failed to create import manager: ${importManager.message}`);\r\n }\r\n\r\n // Use ImportManager to handle both files and directories automatically\r\n if (this._options.debug) {\r\n console.error(`Importing resources from: ${inputPath}`);\r\n }\r\n const importResult = importManager.value.importFromFileSystem(inputPath);\r\n if (importResult.isFailure()) {\r\n return fail(`Failed to import from ${inputPath}: ${importResult.message}`);\r\n }\r\n\r\n if (this._options.verbose) {\r\n console.error(`Successfully imported resources from: ${inputPath}`);\r\n }\r\n\r\n return succeed(undefined);\r\n } catch (error) {\r\n return fail(`Failed to import resources: ${error}`);\r\n }\r\n }\r\n\r\n /**\r\n * Applies filters to imported resources\r\n */\r\n private _applyFilters(original: TsRes.Resources.ResourceManagerBuilder): Result<IFilteredManager> {\r\n if (this._options.contextFilter) {\r\n const tokens = new TsRes.Context.ContextTokens(original.qualifiers);\r\n return tokens.contextTokenToPartialContext(this._options.contextFilter).onSuccess((context) => {\r\n return original\r\n .clone({\r\n filterForContext: context,\r\n reduceQualifiers: this._options.reduceQualifiers\r\n })\r\n .onSuccess((manager) => {\r\n return succeed({ original, manager, context });\r\n });\r\n });\r\n }\r\n return succeed({ original, manager: original });\r\n }\r\n\r\n /**\r\n * Generates the output blob\r\n */\r\n private async _generateBlob(filtered: IFilteredManager): Promise<Result<IResourceBlob>> {\r\n try {\r\n if (this._options.format === 'compiled') {\r\n return this._generateCompiledBlob(filtered);\r\n } else {\r\n return this._generateSourceBlob(filtered);\r\n }\r\n } catch (error) {\r\n return fail(`Failed to generate blob: ${error}`);\r\n }\r\n }\r\n\r\n /**\r\n * Generates a compiled resource collection blob\r\n */\r\n private _generateCompiledBlob(filtered: IFilteredManager): Result<IResourceBlob> {\r\n // Build all resources to ensure they're ready for compilation\r\n return filtered.manager.getCompiledResourceCollection().onSuccess((compiled) => {\r\n const blob: IResourceBlob = {\r\n compiledCollection: compiled\r\n };\r\n\r\n if (this._options.includeMetadata) {\r\n blob.metadata = this._generateResourceInfo(filtered);\r\n }\r\n return succeed(blob);\r\n });\r\n }\r\n\r\n /**\r\n * Generates a source format blob (legacy format)\r\n */\r\n private _generateSourceBlob(filtered: IFilteredManager): Result<IResourceBlob> {\r\n return filtered.manager.getResourceCollectionDecl().onSuccess((resources) => {\r\n const blob: IResourceBlob = { resources };\r\n\r\n if (this._options.includeMetadata) {\r\n blob.metadata = this._generateResourceInfo(filtered);\r\n }\r\n\r\n return succeed(blob);\r\n });\r\n }\r\n\r\n /**\r\n * Generates resource information\r\n */\r\n private _generateResourceInfo(filtered: IFilteredManager): IResourceInfo {\r\n const resourceTypes = Array.from(\r\n new Set(\r\n filtered.manager\r\n .getAllCandidates()\r\n .map((c) => c.resourceType?.key)\r\n .filter(Boolean)\r\n )\r\n ) as string[];\r\n\r\n const qualifiers = Array.from(filtered.manager.qualifiers.keys());\r\n\r\n const info: IResourceInfo = {\r\n totalResources: filtered.original.numResources,\r\n totalCandidates: filtered.original.numCandidates,\r\n filteredResources: filtered.manager.numResources,\r\n filteredCandidates: filtered.manager.numCandidates,\r\n resourceTypes,\r\n qualifiers,\r\n ...(filtered.context ? { context: filtered.context } : undefined)\r\n };\r\n\r\n return info;\r\n }\r\n\r\n /**\r\n * Writes the output blob to the specified output path\r\n */\r\n private async _writeOutput(blob: IResourceBlob): Promise<Result<void>> {\r\n try {\r\n const outputPath = path.resolve(this._options.output);\r\n const outputDir = path.dirname(outputPath);\r\n\r\n // Ensure output directory exists\r\n await fs.mkdir(outputDir, { recursive: true });\r\n\r\n let content: string;\r\n\r\n switch (this._options.format) {\r\n case 'compiled':\r\n // If metadata is included, write the full blob; otherwise, write just the compiled collection\r\n const compiledData = this._options.includeMetadata ? blob : blob.compiledCollection;\r\n content = JSON.stringify(compiledData, null, 2);\r\n break;\r\n case 'source':\r\n content = JSON.stringify(blob, null, 2);\r\n break;\r\n case 'js':\r\n const jsData = blob.compiledCollection || blob;\r\n content = `module.exports = ${JSON.stringify(jsData, null, 2)};`;\r\n break;\r\n case 'ts':\r\n const tsData = blob.compiledCollection || blob;\r\n content = `export const resources = ${JSON.stringify(tsData, null, 2)} as const;`;\r\n break;\r\n case 'binary':\r\n // For binary format, we could use a more efficient serialization\r\n // For now, use JSON as a placeholder\r\n const binaryData = blob.compiledCollection || blob;\r\n content = JSON.stringify(binaryData);\r\n break;\r\n default:\r\n return fail(`Unsupported output format: ${this._options.format}`);\r\n }\r\n\r\n await fs.writeFile(outputPath, content, 'utf-8');\r\n return succeed(undefined);\r\n } catch (error) {\r\n return fail(`Failed to write output: ${error}`);\r\n }\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as TsRes from '@fgv/ts-res';
|
|
2
|
+
/**
|
|
3
|
+
* Default system configuration for ts-res CLI tool
|
|
4
|
+
* This matches the configuration used in the ts-res-browser tool
|
|
5
|
+
*/
|
|
6
|
+
export declare const DEFAULT_SYSTEM_CONFIGURATION: TsRes.Config.Model.ISystemConfiguration;
|
|
7
|
+
//# sourceMappingURL=defaultConfiguration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaultConfiguration.d.ts","sourceRoot":"","sources":["../src/defaultConfiguration.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,KAAK,MAAM,aAAa,CAAC;AAErC;;;GAGG;AACH,eAAO,MAAM,4BAA4B,EAAE,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,oBAiD7D,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025 Erik Fortune
|
|
4
|
+
*
|
|
5
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
* in the Software without restriction, including without limitation the rights
|
|
8
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
* furnished to do so, subject to the following conditions:
|
|
11
|
+
*
|
|
12
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
* copies or substantial portions of the Software.
|
|
14
|
+
*
|
|
15
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
* SOFTWARE.
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.DEFAULT_SYSTEM_CONFIGURATION = void 0;
|
|
25
|
+
/**
|
|
26
|
+
* Default system configuration for ts-res CLI tool
|
|
27
|
+
* This matches the configuration used in the ts-res-browser tool
|
|
28
|
+
*/
|
|
29
|
+
exports.DEFAULT_SYSTEM_CONFIGURATION = {
|
|
30
|
+
name: 'Default CLI Configuration',
|
|
31
|
+
description: 'Built-in default configuration for ts-res CLI tool',
|
|
32
|
+
qualifierTypes: [
|
|
33
|
+
{
|
|
34
|
+
name: 'language',
|
|
35
|
+
systemType: 'language',
|
|
36
|
+
configuration: {}
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: 'territory',
|
|
40
|
+
systemType: 'territory',
|
|
41
|
+
configuration: {}
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'role',
|
|
45
|
+
systemType: 'literal',
|
|
46
|
+
configuration: {
|
|
47
|
+
enumeratedValues: ['admin', 'user', 'guest']
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
qualifiers: [
|
|
52
|
+
{
|
|
53
|
+
name: 'language',
|
|
54
|
+
typeName: 'language',
|
|
55
|
+
token: 'language',
|
|
56
|
+
defaultPriority: 600
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'territory',
|
|
60
|
+
typeName: 'territory',
|
|
61
|
+
token: 'territory',
|
|
62
|
+
defaultPriority: 500
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'role',
|
|
66
|
+
typeName: 'role',
|
|
67
|
+
token: 'role',
|
|
68
|
+
tokenIsOptional: true,
|
|
69
|
+
defaultPriority: 400
|
|
70
|
+
}
|
|
71
|
+
],
|
|
72
|
+
resourceTypes: [
|
|
73
|
+
{
|
|
74
|
+
name: 'json',
|
|
75
|
+
typeName: 'json'
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=defaultConfiguration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaultConfiguration.js","sourceRoot":"","sources":["../src/defaultConfiguration.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;AAIH;;;GAGG;AACU,QAAA,4BAA4B,GAA4C;IACnF,IAAI,EAAE,2BAA2B;IACjC,WAAW,EAAE,oDAAoD;IACjE,cAAc,EAAE;QACd;YACE,IAAI,EAAE,UAAU;YAChB,UAAU,EAAE,UAAU;YACtB,aAAa,EAAE,EAAE;SAClB;QACD;YACE,IAAI,EAAE,WAAW;YACjB,UAAU,EAAE,WAAW;YACvB,aAAa,EAAE,EAAE;SAClB;QACD;YACE,IAAI,EAAE,MAAM;YACZ,UAAU,EAAE,SAAS;YACrB,aAAa,EAAE;gBACb,gBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC;aAC7C;SACF;KACF;IACD,UAAU,EAAE;QACV;YACE,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,UAAU;YACpB,KAAK,EAAE,UAAU;YACjB,eAAe,EAAE,GAAG;SACrB;QACD;YACE,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,WAAW;YACrB,KAAK,EAAE,WAAW;YAClB,eAAe,EAAE,GAAG;SACrB;QACD;YACE,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,MAAM;YACb,eAAe,EAAE,IAAI;YACrB,eAAe,EAAE,GAAG;SACrB;KACF;IACD,aAAa,EAAE;QACb;YACE,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,MAAM;SACjB;KACF;CACF,CAAC","sourcesContent":["/*\n * Copyright (c) 2025 Erik Fortune\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport * as TsRes from '@fgv/ts-res';\n\n/**\n * Default system configuration for ts-res CLI tool\n * This matches the configuration used in the ts-res-browser tool\n */\nexport const DEFAULT_SYSTEM_CONFIGURATION: TsRes.Config.Model.ISystemConfiguration = {\n name: 'Default CLI Configuration',\n description: 'Built-in default configuration for ts-res CLI tool',\n qualifierTypes: [\n {\n name: 'language',\n systemType: 'language',\n configuration: {}\n },\n {\n name: 'territory',\n systemType: 'territory',\n configuration: {}\n },\n {\n name: 'role',\n systemType: 'literal',\n configuration: {\n enumeratedValues: ['admin', 'user', 'guest']\n }\n }\n ],\n qualifiers: [\n {\n name: 'language',\n typeName: 'language',\n token: 'language',\n defaultPriority: 600\n },\n {\n name: 'territory',\n typeName: 'territory',\n token: 'territory',\n defaultPriority: 500\n },\n {\n name: 'role',\n typeName: 'role',\n token: 'role',\n tokenIsOptional: true,\n defaultPriority: 400\n }\n ],\n resourceTypes: [\n {\n name: 'json',\n typeName: 'json'\n }\n ]\n};\n"]}
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAsBA,cAAc,OAAO,CAAC;AACtB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025 Erik Fortune
|
|
4
|
+
*
|
|
5
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
* in the Software without restriction, including without limitation the rights
|
|
8
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
* furnished to do so, subject to the following conditions:
|
|
11
|
+
*
|
|
12
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
* copies or substantial portions of the Software.
|
|
14
|
+
*
|
|
15
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
* SOFTWARE.
|
|
22
|
+
*/
|
|
23
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
26
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
27
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
28
|
+
}
|
|
29
|
+
Object.defineProperty(o, k2, desc);
|
|
30
|
+
}) : (function(o, m, k, k2) {
|
|
31
|
+
if (k2 === undefined) k2 = k;
|
|
32
|
+
o[k2] = m[k];
|
|
33
|
+
}));
|
|
34
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
35
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
36
|
+
};
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
__exportStar(require("./cli"), exports);
|
|
39
|
+
__exportStar(require("./compiler"), exports);
|
|
40
|
+
__exportStar(require("./options"), exports);
|
|
41
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;;;;;;;;;;;;;;;AAEH,wCAAsB;AACtB,6CAA2B;AAC3B,4CAA0B","sourcesContent":["/*\r\n * Copyright (c) 2025 Erik Fortune\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy\r\n * of this software and associated documentation files (the \"Software\"), to deal\r\n * in the Software without restriction, including without limitation the rights\r\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r\n * copies of the Software, and to permit persons to whom the Software is\r\n * furnished to do so, subject to the following conditions:\r\n *\r\n * The above copyright notice and this permission notice shall be included in all\r\n * copies or substantial portions of the Software.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r\n * SOFTWARE.\r\n */\r\n\r\nexport * from './cli';\r\nexport * from './compiler';\r\nexport * from './options';\r\n"]}
|