@fgv/ts-res-cli 5.0.0-8 → 5.0.0-9

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.
@@ -2,5 +2,5 @@
2
2
  {"kind":"O","text":" ---- build started ---- \n"}
3
3
  {"kind":"O","text":"[build:typescript] Using TypeScript version 5.8.3\n"}
4
4
  {"kind":"O","text":"[build:lint] Using ESLint version 8.57.0\n"}
5
- {"kind":"O","text":" ---- build finished (5.927s) ---- \n"}
6
- {"kind":"O","text":"-------------------- Finished (5.931s) --------------------\n"}
5
+ {"kind":"O","text":" ---- build finished (5.929s) ---- \n"}
6
+ {"kind":"O","text":"-------------------- Finished (5.934s) --------------------\n"}
@@ -2,5 +2,5 @@
2
2
  {"kind":"O","text":" ---- build started ---- \n"}
3
3
  {"kind":"O","text":"[build:typescript] Using TypeScript version 5.8.3\n"}
4
4
  {"kind":"O","text":"[build:lint] Using ESLint version 8.57.0\n"}
5
- {"kind":"O","text":" ---- build finished (5.927s) ---- \n"}
6
- {"kind":"O","text":"-------------------- Finished (5.931s) --------------------\n"}
5
+ {"kind":"O","text":" ---- build finished (5.929s) ---- \n"}
6
+ {"kind":"O","text":"-------------------- Finished (5.934s) --------------------\n"}
@@ -1,3 +1,3 @@
1
1
  {
2
- "nonCachedDurationMs": 6369.705780999997
2
+ "nonCachedDurationMs": 6370.66850900001
3
3
  }
package/README.md CHANGED
@@ -33,6 +33,13 @@ ts-res-compile compile \
33
33
  -o ./dist/resources.ts \
34
34
  --format ts \
35
35
  --include-metadata
36
+
37
+ # Create a complete bundle with metadata and configuration
38
+ ts-res-compile compile \
39
+ -i ./resources \
40
+ -o ./dist/resources.bundle.json \
41
+ --format bundle \
42
+ --include-metadata
36
43
  ```
37
44
 
38
45
  ### Validate Resources
@@ -66,7 +73,7 @@ Compiles resources from input to output format.
66
73
 
67
74
  **Optional Options:**
68
75
  - `-c, --context <json>` - Context filter for resources (JSON string)
69
- - `-f, --format <format>` - Output format (json, js, ts, binary) [default: json]
76
+ - `-f, --format <format>` - Output format (compiled, source, js, ts, binary, bundle) [default: compiled]
70
77
  - `--debug` - Include debug information [default: false]
71
78
  - `-v, --verbose` - Verbose output [default: false]
72
79
  - `-q, --quiet` - Quiet output [default: false]
@@ -134,7 +141,8 @@ The CLI supports the following input formats:
134
141
 
135
142
  ## Output Formats
136
143
 
137
- ### JSON (default)
144
+ ### Compiled (default)
145
+ Compiled resource collection optimized for runtime use:
138
146
  ```json
139
147
  {
140
148
  "resources": {
@@ -145,6 +153,46 @@ The CLI supports the following input formats:
145
153
  }
146
154
  ```
147
155
 
156
+ ### Source
157
+ Original resource collection format:
158
+ ```json
159
+ {
160
+ "resources": [
161
+ {
162
+ "id": "welcome.message",
163
+ "resourceTypeName": "json",
164
+ "candidates": [
165
+ {
166
+ "json": { "text": "Welcome!" },
167
+ "conditions": { "language": "en" }
168
+ }
169
+ ]
170
+ }
171
+ ]
172
+ }
173
+ ```
174
+
175
+ ### Bundle
176
+ Complete resource bundle with metadata, configuration, and compiled resources:
177
+ ```json
178
+ {
179
+ "metadata": {
180
+ "dateBuilt": "2025-01-01T00:00:00.000Z",
181
+ "checksum": "abc12345",
182
+ "version": "1.0.0",
183
+ "description": "Generated bundle from ts-res-cli"
184
+ },
185
+ "config": {
186
+ "qualifierTypes": [...],
187
+ "qualifiers": [...],
188
+ "resourceTypes": [...]
189
+ },
190
+ "compiledCollection": {
191
+ "resources": {...}
192
+ }
193
+ }
194
+ ```
195
+
148
196
  ### JavaScript
149
197
  ```javascript
150
198
  module.exports = {
package/lib/cli.js CHANGED
@@ -90,7 +90,7 @@ class TsResCliApp {
90
90
  .option('-c, --context <json>', 'Context filter for resources (JSON string)')
91
91
  .option('--context-filter <token>', 'Context filter token (pipe-separated, e.g., "language=en-US|territory=US")')
92
92
  .option('--qualifier-defaults <token>', 'Qualifier default values token (pipe-separated, e.g., "language=en-US,en-CA|territory=US")')
93
- .option('-f, --format <format>', 'Output format', 'compiled')
93
+ .option('-f, --format <format>', 'Output format (compiled, source, js, ts, binary, bundle)', 'compiled')
94
94
  .option('--debug', 'Include debug information', false)
95
95
  .option('-v, --verbose', 'Verbose output', false)
96
96
  .option('-q, --quiet', 'Quiet output', false)
@@ -419,7 +419,7 @@ class TsResCliApp {
419
419
  _parseCompileOptions(options) {
420
420
  try {
421
421
  const format = options.format;
422
- if (!['compiled', 'source', 'js', 'ts', 'binary'].includes(format)) {
422
+ if (!['compiled', 'source', 'js', 'ts', 'binary', 'bundle'].includes(format)) {
423
423
  return (0, ts_utils_1.fail)(`Invalid format: ${format}`);
424
424
  }
425
425
  // Convert JSON context to contextFilter if provided
package/lib/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.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 { Command } from 'commander';\r\nimport { Result, succeed, fail } from '@fgv/ts-utils';\r\nimport { ICompileOptions, OutputFormat } from './options';\r\nimport * as TsRes from '@fgv/ts-res';\r\n\r\n/**\r\n * Command-line options for the compile command\r\n */\r\ninterface ICompileCommandOptions {\r\n input: string;\r\n output: string;\r\n config?: string;\r\n context?: string;\r\n contextFilter?: string;\r\n qualifierDefaults?: string;\r\n format: string;\r\n debug?: boolean;\r\n verbose?: boolean;\r\n quiet?: boolean;\r\n validate?: boolean;\r\n includeMetadata?: boolean;\r\n resourceTypes?: string;\r\n maxDistance?: number;\r\n reduceQualifiers?: boolean;\r\n}\r\n\r\n/**\r\n * Command-line options for the validate command\r\n */\r\ninterface IValidateCommandOptions {\r\n input: string;\r\n config?: string;\r\n context?: string;\r\n contextFilter?: string;\r\n qualifierDefaults?: string;\r\n verbose?: boolean;\r\n quiet?: boolean;\r\n reduceQualifiers?: boolean;\r\n}\r\n\r\n/**\r\n * Command-line options for the info command\r\n */\r\ninterface IInfoCommandOptions {\r\n input: string;\r\n config?: string;\r\n context?: string;\r\n contextFilter?: string;\r\n qualifierDefaults?: string;\r\n resourceTypes?: string;\r\n maxDistance?: number;\r\n reduceQualifiers?: boolean;\r\n}\r\n\r\n/**\r\n * Command-line options for the config command\r\n */\r\ninterface IConfigCommandOptions {\r\n name?: string;\r\n output?: string;\r\n validate?: string;\r\n normalize?: string;\r\n qualifierDefaults?: string;\r\n list?: boolean;\r\n}\r\n\r\nimport { ResourceCompiler } from './compiler';\r\n\r\n/**\r\n * Main CLI class for ts-res-compile\r\n */\r\nexport class TsResCliApp {\r\n private readonly _program: Command;\r\n\r\n public constructor() {\r\n this._program = new Command();\r\n this._setupCommands();\r\n }\r\n\r\n /**\r\n * Runs the CLI with the provided arguments\r\n */\r\n public async run(argv: string[]): Promise<void> {\r\n await this._program.parseAsync(argv);\r\n }\r\n\r\n /**\r\n * Sets up the CLI commands and options\r\n */\r\n private _setupCommands(): void {\r\n this._program\r\n .name('ts-res-compile')\r\n .description('Compile and optimize ts-res resources')\r\n .version('1.0.0');\r\n\r\n this._program\r\n .command('compile')\r\n .description('Compile resources from input to output format')\r\n .requiredOption('-i, --input <path>', 'Input file or directory path')\r\n .requiredOption('-o, --output <path>', 'Output file path')\r\n .option(\r\n '--config <name|path>',\r\n 'Predefined configuration name or system configuration file path (JSON, ISystemConfiguration format)'\r\n )\r\n .option('-c, --context <json>', 'Context filter for resources (JSON string)')\r\n .option(\r\n '--context-filter <token>',\r\n 'Context filter token (pipe-separated, e.g., \"language=en-US|territory=US\")'\r\n )\r\n .option(\r\n '--qualifier-defaults <token>',\r\n 'Qualifier default values token (pipe-separated, e.g., \"language=en-US,en-CA|territory=US\")'\r\n )\r\n .option('-f, --format <format>', 'Output format', 'compiled')\r\n .option('--debug', 'Include debug information', false)\r\n .option('-v, --verbose', 'Verbose output', false)\r\n .option('-q, --quiet', 'Quiet output', false)\r\n .option('--validate', 'Validate resources during compilation', true)\r\n .option('--include-metadata', 'Include resource metadata in output', false)\r\n .option('--resource-types <types>', 'Resource type filter (comma-separated)')\r\n .option('--max-distance <number>', 'Maximum distance for language matching', parseInt)\r\n .option(\r\n '--reduce-qualifiers',\r\n 'Remove perfectly matching qualifier conditions from filtered resources',\r\n false\r\n )\r\n .action(async (options) => {\r\n await this._handleCompileCommand(options);\r\n });\r\n\r\n this._program\r\n .command('validate')\r\n .description('Validate resources without compilation')\r\n .requiredOption('-i, --input <path>', 'Input file or directory path')\r\n .option(\r\n '--config <name|path>',\r\n 'Predefined configuration name or system configuration file path (JSON, ISystemConfiguration format)'\r\n )\r\n .option('-c, --context <json>', 'Context filter for resources (JSON string)')\r\n .option(\r\n '--context-filter <token>',\r\n 'Context filter token (pipe-separated, e.g., \"language=en-US|territory=US\")'\r\n )\r\n .option(\r\n '--qualifier-defaults <token>',\r\n 'Qualifier default values token (pipe-separated, e.g., \"language=en-US,en-CA|territory=US\")'\r\n )\r\n .option('-v, --verbose', 'Verbose output', false)\r\n .option('-q, --quiet', 'Quiet output', false)\r\n .option(\r\n '--reduce-qualifiers',\r\n 'Remove perfectly matching qualifier conditions from filtered resources',\r\n false\r\n )\r\n .action(async (options) => {\r\n await this._handleValidateCommand(options);\r\n });\r\n\r\n this._program\r\n .command('info')\r\n .description('Show information about resources')\r\n .requiredOption('-i, --input <path>', 'Input file or directory path')\r\n .option(\r\n '--config <name|path>',\r\n 'Predefined configuration name or system configuration file path (JSON, ISystemConfiguration format)'\r\n )\r\n .option('-c, --context <json>', 'Context filter for resources (JSON string)')\r\n .option(\r\n '--context-filter <token>',\r\n 'Context filter token (pipe-separated, e.g., \"language=en-US|territory=US\")'\r\n )\r\n .option(\r\n '--qualifier-defaults <token>',\r\n 'Qualifier default values token (pipe-separated, e.g., \"language=en-US,en-CA|territory=US\")'\r\n )\r\n .option('--resource-types <types>', 'Resource type filter (comma-separated)')\r\n .option('--max-distance <number>', 'Maximum distance for language matching', parseInt)\r\n .option(\r\n '--reduce-qualifiers',\r\n 'Remove perfectly matching qualifier conditions from filtered resources',\r\n false\r\n )\r\n .action(async (options) => {\r\n await this._handleInfoCommand(options);\r\n });\r\n\r\n this._program\r\n .command('config')\r\n .description('Manage system configurations')\r\n .option('-n, --name <name>', 'Predefined configuration name to print')\r\n .option('-o, --output <path>', 'Output file path to save configuration')\r\n .option('--validate <path>', 'Validate a configuration file')\r\n .option('--normalize <path>', 'Normalize and validate a configuration file')\r\n .option(\r\n '--qualifier-defaults <token>',\r\n 'Qualifier default values token (pipe-separated, e.g., \"language=en-US,en-CA|territory=US\")'\r\n )\r\n .option('-l, --list', 'List all available predefined configurations')\r\n .action(async (options) => {\r\n await this._handleConfigCommand(options);\r\n });\r\n }\r\n\r\n /**\r\n * Handles the compile command\r\n */\r\n private async _handleCompileCommand(options: ICompileCommandOptions): Promise<void> {\r\n const compileOptions = this._parseCompileOptions(options);\r\n if (compileOptions.isFailure()) {\r\n console.error(`Error: ${compileOptions.message}`);\r\n process.exit(1);\r\n }\r\n\r\n const compiler = new ResourceCompiler(compileOptions.value);\r\n const result = await compiler.compile();\r\n\r\n if (result.isFailure()) {\r\n console.error(`Error: ${result.message}`);\r\n process.exit(1);\r\n }\r\n\r\n if (!options.quiet && options.output) {\r\n console.log(`Successfully compiled resources to ${options.output}`);\r\n }\r\n }\r\n\r\n /**\r\n * Handles the validate command\r\n */\r\n private async _handleValidateCommand(options: IValidateCommandOptions): Promise<void> {\r\n // Convert JSON context to contextFilter if provided\r\n let contextFilter = options.contextFilter;\r\n if (options.context && !contextFilter) {\r\n try {\r\n const contextObj = JSON.parse(options.context);\r\n const tokens: string[] = [];\r\n for (const [key, value] of Object.entries(contextObj)) {\r\n tokens.push(`${key}=${value}`);\r\n }\r\n contextFilter = tokens.join('|');\r\n } catch (error) {\r\n console.error(`Error: Invalid context JSON: ${error}`);\r\n process.exit(1);\r\n }\r\n }\r\n\r\n const validateOptions: ICompileOptions = {\r\n input: options.input,\r\n output: '', // Not used for validation\r\n config: options.config,\r\n contextFilter,\r\n qualifierDefaults: options.qualifierDefaults,\r\n format: 'compiled',\r\n debug: false,\r\n verbose: options.verbose || false,\r\n quiet: options.quiet || false,\r\n validate: true,\r\n includeMetadata: false,\r\n reduceQualifiers: options.reduceQualifiers || false\r\n };\r\n\r\n const compiler = new ResourceCompiler(validateOptions);\r\n const result = await compiler.validate();\r\n\r\n if (result.isFailure()) {\r\n console.error(`Validation failed: ${result.message}`);\r\n process.exit(1);\r\n }\r\n\r\n if (!options.quiet) {\r\n console.log('Resources validated successfully');\r\n }\r\n }\r\n\r\n /**\r\n * Handles the info command\r\n */\r\n private async _handleInfoCommand(options: IInfoCommandOptions): Promise<void> {\r\n // Convert JSON context to contextFilter if provided\r\n let contextFilter = options.contextFilter;\r\n if (options.context && !contextFilter) {\r\n try {\r\n const contextObj = JSON.parse(options.context);\r\n const tokens: string[] = [];\r\n for (const [key, value] of Object.entries(contextObj)) {\r\n tokens.push(`${key}=${value}`);\r\n }\r\n contextFilter = tokens.join('|');\r\n } catch (error) {\r\n console.error(`Error: Invalid context JSON: ${error}`);\r\n process.exit(1);\r\n }\r\n }\r\n\r\n const infoOptions: ICompileOptions = {\r\n input: options.input,\r\n output: '', // Not used for info\r\n config: options.config,\r\n format: 'compiled',\r\n debug: false,\r\n verbose: false,\r\n quiet: false,\r\n validate: false,\r\n includeMetadata: true,\r\n contextFilter,\r\n qualifierDefaults: options.qualifierDefaults,\r\n resourceTypes: options.resourceTypes,\r\n maxDistance: options.maxDistance,\r\n reduceQualifiers: options.reduceQualifiers || false\r\n };\r\n\r\n const compiler = new ResourceCompiler(infoOptions);\r\n const result = await compiler.getInfo();\r\n\r\n if (result.isFailure()) {\r\n console.error(`Error: ${result.message}`);\r\n process.exit(1);\r\n }\r\n\r\n console.log(JSON.stringify(result.value, null, 2));\r\n }\r\n\r\n /**\r\n * Handles the config command\r\n */\r\n private async _handleConfigCommand(options: IConfigCommandOptions): Promise<void> {\r\n try {\r\n // List all predefined configurations\r\n if (options.list) {\r\n console.log('Available predefined configurations:');\r\n console.log('- default');\r\n console.log('- language-priority');\r\n console.log('- territory-priority');\r\n console.log('- extended-example');\r\n return;\r\n }\r\n\r\n // Print a specific predefined configuration\r\n if (options.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\r\n if (!predefinedNames.includes(options.name as TsRes.Config.PredefinedSystemConfiguration)) {\r\n console.error(`Error: Predefined configuration '${options.name}' not found`);\r\n console.error(\r\n 'Available configurations: default, language-priority, territory-priority, extended-example'\r\n );\r\n process.exit(1);\r\n }\r\n\r\n const configResult = TsRes.Config.getPredefinedDeclaration(\r\n options.name as TsRes.Config.PredefinedSystemConfiguration\r\n );\r\n if (configResult.isFailure()) {\r\n console.error(\r\n `Error: Failed to load predefined configuration '${options.name}': ${configResult.message}`\r\n );\r\n process.exit(1);\r\n }\r\n\r\n let config = configResult.value;\r\n\r\n // Apply qualifier defaults if provided\r\n if (options.qualifierDefaults) {\r\n const tempSystemConfigResult = TsRes.Config.SystemConfiguration.create(config);\r\n if (tempSystemConfigResult.isFailure()) {\r\n console.error(`Error: Failed to create system configuration: ${tempSystemConfigResult.message}`);\r\n process.exit(1);\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(options.qualifierDefaults);\r\n if (defaultsResult.isFailure()) {\r\n console.error(`Error: Failed to parse qualifier defaults: ${defaultsResult.message}`);\r\n process.exit(1);\r\n }\r\n\r\n const updatedConfigResult = TsRes.Config.updateSystemConfigurationQualifierDefaultValues(\r\n config,\r\n defaultsResult.value\r\n );\r\n if (updatedConfigResult.isFailure()) {\r\n console.error(`Error: Failed to apply qualifier defaults: ${updatedConfigResult.message}`);\r\n process.exit(1);\r\n }\r\n\r\n config = updatedConfigResult.value;\r\n }\r\n\r\n const output = JSON.stringify(config, null, 2);\r\n\r\n if (options.output) {\r\n const fs = await import('fs').then((m) => m.promises);\r\n const path = await import('path');\r\n const outputPath = path.resolve(options.output);\r\n const outputDir = path.dirname(outputPath);\r\n\r\n await fs.mkdir(outputDir, { recursive: true });\r\n await fs.writeFile(outputPath, output, 'utf-8');\r\n console.log(`Configuration saved to: ${outputPath}`);\r\n } else {\r\n console.log(output);\r\n }\r\n return;\r\n }\r\n\r\n // Validate a configuration file\r\n if (options.validate) {\r\n const fs = await import('fs').then((m) => m.promises);\r\n const path = await import('path');\r\n\r\n const configPath = path.resolve(options.validate);\r\n const configContent = await fs.readFile(configPath, 'utf-8');\r\n const configData = JSON.parse(configContent);\r\n\r\n const configResult = TsRes.Config.Convert.systemConfiguration.convert(configData);\r\n if (configResult.isFailure()) {\r\n console.error(`Validation failed: ${configResult.message}`);\r\n process.exit(1);\r\n }\r\n\r\n console.log(`Configuration file '${configPath}' is valid`);\r\n return;\r\n }\r\n\r\n // Normalize a configuration file\r\n if (options.normalize) {\r\n const fs = await import('fs').then((m) => m.promises);\r\n const path = await import('path');\r\n\r\n const configPath = path.resolve(options.normalize);\r\n const configContent = await fs.readFile(configPath, 'utf-8');\r\n const configData = JSON.parse(configContent);\r\n\r\n const configResult = TsRes.Config.Convert.systemConfiguration.convert(configData);\r\n if (configResult.isFailure()) {\r\n console.error(`Normalization failed: ${configResult.message}`);\r\n process.exit(1);\r\n }\r\n\r\n let normalizedConfig = configResult.value;\r\n\r\n // Apply qualifier defaults if provided\r\n if (options.qualifierDefaults) {\r\n const tempSystemConfigResult = TsRes.Config.SystemConfiguration.create(normalizedConfig);\r\n if (tempSystemConfigResult.isFailure()) {\r\n console.error(`Error: Failed to create system configuration: ${tempSystemConfigResult.message}`);\r\n process.exit(1);\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(options.qualifierDefaults);\r\n if (defaultsResult.isFailure()) {\r\n console.error(`Error: Failed to parse qualifier defaults: ${defaultsResult.message}`);\r\n process.exit(1);\r\n }\r\n\r\n const updatedConfigResult = TsRes.Config.updateSystemConfigurationQualifierDefaultValues(\r\n normalizedConfig,\r\n defaultsResult.value\r\n );\r\n if (updatedConfigResult.isFailure()) {\r\n console.error(`Error: Failed to apply qualifier defaults: ${updatedConfigResult.message}`);\r\n process.exit(1);\r\n }\r\n\r\n normalizedConfig = updatedConfigResult.value;\r\n }\r\n\r\n const output = JSON.stringify(normalizedConfig, null, 2);\r\n\r\n if (options.output) {\r\n const outputPath = path.resolve(options.output);\r\n const outputDir = path.dirname(outputPath);\r\n\r\n await fs.mkdir(outputDir, { recursive: true });\r\n await fs.writeFile(outputPath, output, 'utf-8');\r\n console.log(`Normalized configuration saved to: ${outputPath}`);\r\n } else {\r\n console.log(output);\r\n }\r\n return;\r\n }\r\n\r\n // If no specific action, print default configuration\r\n const defaultResult = TsRes.Config.getPredefinedDeclaration('default');\r\n if (defaultResult.isFailure()) {\r\n console.error(`Error: Default configuration not available`);\r\n process.exit(1);\r\n }\r\n\r\n let defaultConfig = defaultResult.value;\r\n\r\n // Apply qualifier defaults if provided\r\n if (options.qualifierDefaults) {\r\n const tempSystemConfigResult = TsRes.Config.SystemConfiguration.create(defaultConfig);\r\n if (tempSystemConfigResult.isFailure()) {\r\n console.error(`Error: Failed to create system configuration: ${tempSystemConfigResult.message}`);\r\n process.exit(1);\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(options.qualifierDefaults);\r\n if (defaultsResult.isFailure()) {\r\n console.error(`Error: Failed to parse qualifier defaults: ${defaultsResult.message}`);\r\n process.exit(1);\r\n }\r\n\r\n const updatedConfigResult = TsRes.Config.updateSystemConfigurationQualifierDefaultValues(\r\n defaultConfig,\r\n defaultsResult.value\r\n );\r\n if (updatedConfigResult.isFailure()) {\r\n console.error(`Error: Failed to apply qualifier defaults: ${updatedConfigResult.message}`);\r\n process.exit(1);\r\n }\r\n\r\n defaultConfig = updatedConfigResult.value;\r\n }\r\n\r\n console.log(JSON.stringify(defaultConfig, null, 2));\r\n } catch (error) {\r\n console.error(`Error: ${error}`);\r\n process.exit(1);\r\n }\r\n }\r\n\r\n /**\r\n * Parses and validates compile options\r\n */\r\n private _parseCompileOptions(options: ICompileCommandOptions): Result<ICompileOptions> {\r\n try {\r\n const format = options.format as OutputFormat;\r\n if (!['compiled', 'source', 'js', 'ts', 'binary'].includes(format)) {\r\n return fail(`Invalid format: ${format}`);\r\n }\r\n\r\n // Convert JSON context to contextFilter if provided\r\n let contextFilter = options.contextFilter;\r\n if (options.context && !contextFilter) {\r\n try {\r\n const contextObj = JSON.parse(options.context);\r\n const tokens: string[] = [];\r\n for (const [key, value] of Object.entries(contextObj)) {\r\n tokens.push(`${key}=${value}`);\r\n }\r\n contextFilter = tokens.join('|');\r\n } catch (error) {\r\n return fail(`Invalid context JSON: ${error}`);\r\n }\r\n }\r\n\r\n const compileOptions: ICompileOptions = {\r\n input: options.input,\r\n output: options.output,\r\n config: options.config,\r\n contextFilter,\r\n qualifierDefaults: options.qualifierDefaults,\r\n format,\r\n debug: options.debug || false,\r\n verbose: options.verbose || false,\r\n quiet: options.quiet || false,\r\n validate: options.validate !== false,\r\n includeMetadata: options.includeMetadata || false,\r\n resourceTypes: options.resourceTypes,\r\n maxDistance: options.maxDistance,\r\n reduceQualifiers: options.reduceQualifiers || false\r\n };\r\n\r\n return succeed(compileOptions);\r\n } catch (error) {\r\n return fail(`Failed to parse options: ${error}`);\r\n }\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.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 { Command } from 'commander';\r\nimport { Result, succeed, fail } from '@fgv/ts-utils';\r\nimport { ICompileOptions, OutputFormat } from './options';\r\nimport * as TsRes from '@fgv/ts-res';\r\n\r\n/**\r\n * Command-line options for the compile command\r\n */\r\ninterface ICompileCommandOptions {\r\n input: string;\r\n output: string;\r\n config?: string;\r\n context?: string;\r\n contextFilter?: string;\r\n qualifierDefaults?: string;\r\n format: string;\r\n debug?: boolean;\r\n verbose?: boolean;\r\n quiet?: boolean;\r\n validate?: boolean;\r\n includeMetadata?: boolean;\r\n resourceTypes?: string;\r\n maxDistance?: number;\r\n reduceQualifiers?: boolean;\r\n}\r\n\r\n/**\r\n * Command-line options for the validate command\r\n */\r\ninterface IValidateCommandOptions {\r\n input: string;\r\n config?: string;\r\n context?: string;\r\n contextFilter?: string;\r\n qualifierDefaults?: string;\r\n verbose?: boolean;\r\n quiet?: boolean;\r\n reduceQualifiers?: boolean;\r\n}\r\n\r\n/**\r\n * Command-line options for the info command\r\n */\r\ninterface IInfoCommandOptions {\r\n input: string;\r\n config?: string;\r\n context?: string;\r\n contextFilter?: string;\r\n qualifierDefaults?: string;\r\n resourceTypes?: string;\r\n maxDistance?: number;\r\n reduceQualifiers?: boolean;\r\n}\r\n\r\n/**\r\n * Command-line options for the config command\r\n */\r\ninterface IConfigCommandOptions {\r\n name?: string;\r\n output?: string;\r\n validate?: string;\r\n normalize?: string;\r\n qualifierDefaults?: string;\r\n list?: boolean;\r\n}\r\n\r\nimport { ResourceCompiler } from './compiler';\r\n\r\n/**\r\n * Main CLI class for ts-res-compile\r\n */\r\nexport class TsResCliApp {\r\n private readonly _program: Command;\r\n\r\n public constructor() {\r\n this._program = new Command();\r\n this._setupCommands();\r\n }\r\n\r\n /**\r\n * Runs the CLI with the provided arguments\r\n */\r\n public async run(argv: string[]): Promise<void> {\r\n await this._program.parseAsync(argv);\r\n }\r\n\r\n /**\r\n * Sets up the CLI commands and options\r\n */\r\n private _setupCommands(): void {\r\n this._program\r\n .name('ts-res-compile')\r\n .description('Compile and optimize ts-res resources')\r\n .version('1.0.0');\r\n\r\n this._program\r\n .command('compile')\r\n .description('Compile resources from input to output format')\r\n .requiredOption('-i, --input <path>', 'Input file or directory path')\r\n .requiredOption('-o, --output <path>', 'Output file path')\r\n .option(\r\n '--config <name|path>',\r\n 'Predefined configuration name or system configuration file path (JSON, ISystemConfiguration format)'\r\n )\r\n .option('-c, --context <json>', 'Context filter for resources (JSON string)')\r\n .option(\r\n '--context-filter <token>',\r\n 'Context filter token (pipe-separated, e.g., \"language=en-US|territory=US\")'\r\n )\r\n .option(\r\n '--qualifier-defaults <token>',\r\n 'Qualifier default values token (pipe-separated, e.g., \"language=en-US,en-CA|territory=US\")'\r\n )\r\n .option('-f, --format <format>', 'Output format (compiled, source, js, ts, binary, bundle)', 'compiled')\r\n .option('--debug', 'Include debug information', false)\r\n .option('-v, --verbose', 'Verbose output', false)\r\n .option('-q, --quiet', 'Quiet output', false)\r\n .option('--validate', 'Validate resources during compilation', true)\r\n .option('--include-metadata', 'Include resource metadata in output', false)\r\n .option('--resource-types <types>', 'Resource type filter (comma-separated)')\r\n .option('--max-distance <number>', 'Maximum distance for language matching', parseInt)\r\n .option(\r\n '--reduce-qualifiers',\r\n 'Remove perfectly matching qualifier conditions from filtered resources',\r\n false\r\n )\r\n .action(async (options) => {\r\n await this._handleCompileCommand(options);\r\n });\r\n\r\n this._program\r\n .command('validate')\r\n .description('Validate resources without compilation')\r\n .requiredOption('-i, --input <path>', 'Input file or directory path')\r\n .option(\r\n '--config <name|path>',\r\n 'Predefined configuration name or system configuration file path (JSON, ISystemConfiguration format)'\r\n )\r\n .option('-c, --context <json>', 'Context filter for resources (JSON string)')\r\n .option(\r\n '--context-filter <token>',\r\n 'Context filter token (pipe-separated, e.g., \"language=en-US|territory=US\")'\r\n )\r\n .option(\r\n '--qualifier-defaults <token>',\r\n 'Qualifier default values token (pipe-separated, e.g., \"language=en-US,en-CA|territory=US\")'\r\n )\r\n .option('-v, --verbose', 'Verbose output', false)\r\n .option('-q, --quiet', 'Quiet output', false)\r\n .option(\r\n '--reduce-qualifiers',\r\n 'Remove perfectly matching qualifier conditions from filtered resources',\r\n false\r\n )\r\n .action(async (options) => {\r\n await this._handleValidateCommand(options);\r\n });\r\n\r\n this._program\r\n .command('info')\r\n .description('Show information about resources')\r\n .requiredOption('-i, --input <path>', 'Input file or directory path')\r\n .option(\r\n '--config <name|path>',\r\n 'Predefined configuration name or system configuration file path (JSON, ISystemConfiguration format)'\r\n )\r\n .option('-c, --context <json>', 'Context filter for resources (JSON string)')\r\n .option(\r\n '--context-filter <token>',\r\n 'Context filter token (pipe-separated, e.g., \"language=en-US|territory=US\")'\r\n )\r\n .option(\r\n '--qualifier-defaults <token>',\r\n 'Qualifier default values token (pipe-separated, e.g., \"language=en-US,en-CA|territory=US\")'\r\n )\r\n .option('--resource-types <types>', 'Resource type filter (comma-separated)')\r\n .option('--max-distance <number>', 'Maximum distance for language matching', parseInt)\r\n .option(\r\n '--reduce-qualifiers',\r\n 'Remove perfectly matching qualifier conditions from filtered resources',\r\n false\r\n )\r\n .action(async (options) => {\r\n await this._handleInfoCommand(options);\r\n });\r\n\r\n this._program\r\n .command('config')\r\n .description('Manage system configurations')\r\n .option('-n, --name <name>', 'Predefined configuration name to print')\r\n .option('-o, --output <path>', 'Output file path to save configuration')\r\n .option('--validate <path>', 'Validate a configuration file')\r\n .option('--normalize <path>', 'Normalize and validate a configuration file')\r\n .option(\r\n '--qualifier-defaults <token>',\r\n 'Qualifier default values token (pipe-separated, e.g., \"language=en-US,en-CA|territory=US\")'\r\n )\r\n .option('-l, --list', 'List all available predefined configurations')\r\n .action(async (options) => {\r\n await this._handleConfigCommand(options);\r\n });\r\n }\r\n\r\n /**\r\n * Handles the compile command\r\n */\r\n private async _handleCompileCommand(options: ICompileCommandOptions): Promise<void> {\r\n const compileOptions = this._parseCompileOptions(options);\r\n if (compileOptions.isFailure()) {\r\n console.error(`Error: ${compileOptions.message}`);\r\n process.exit(1);\r\n }\r\n\r\n const compiler = new ResourceCompiler(compileOptions.value);\r\n const result = await compiler.compile();\r\n\r\n if (result.isFailure()) {\r\n console.error(`Error: ${result.message}`);\r\n process.exit(1);\r\n }\r\n\r\n if (!options.quiet && options.output) {\r\n console.log(`Successfully compiled resources to ${options.output}`);\r\n }\r\n }\r\n\r\n /**\r\n * Handles the validate command\r\n */\r\n private async _handleValidateCommand(options: IValidateCommandOptions): Promise<void> {\r\n // Convert JSON context to contextFilter if provided\r\n let contextFilter = options.contextFilter;\r\n if (options.context && !contextFilter) {\r\n try {\r\n const contextObj = JSON.parse(options.context);\r\n const tokens: string[] = [];\r\n for (const [key, value] of Object.entries(contextObj)) {\r\n tokens.push(`${key}=${value}`);\r\n }\r\n contextFilter = tokens.join('|');\r\n } catch (error) {\r\n console.error(`Error: Invalid context JSON: ${error}`);\r\n process.exit(1);\r\n }\r\n }\r\n\r\n const validateOptions: ICompileOptions = {\r\n input: options.input,\r\n output: '', // Not used for validation\r\n config: options.config,\r\n contextFilter,\r\n qualifierDefaults: options.qualifierDefaults,\r\n format: 'compiled',\r\n debug: false,\r\n verbose: options.verbose || false,\r\n quiet: options.quiet || false,\r\n validate: true,\r\n includeMetadata: false,\r\n reduceQualifiers: options.reduceQualifiers || false\r\n };\r\n\r\n const compiler = new ResourceCompiler(validateOptions);\r\n const result = await compiler.validate();\r\n\r\n if (result.isFailure()) {\r\n console.error(`Validation failed: ${result.message}`);\r\n process.exit(1);\r\n }\r\n\r\n if (!options.quiet) {\r\n console.log('Resources validated successfully');\r\n }\r\n }\r\n\r\n /**\r\n * Handles the info command\r\n */\r\n private async _handleInfoCommand(options: IInfoCommandOptions): Promise<void> {\r\n // Convert JSON context to contextFilter if provided\r\n let contextFilter = options.contextFilter;\r\n if (options.context && !contextFilter) {\r\n try {\r\n const contextObj = JSON.parse(options.context);\r\n const tokens: string[] = [];\r\n for (const [key, value] of Object.entries(contextObj)) {\r\n tokens.push(`${key}=${value}`);\r\n }\r\n contextFilter = tokens.join('|');\r\n } catch (error) {\r\n console.error(`Error: Invalid context JSON: ${error}`);\r\n process.exit(1);\r\n }\r\n }\r\n\r\n const infoOptions: ICompileOptions = {\r\n input: options.input,\r\n output: '', // Not used for info\r\n config: options.config,\r\n format: 'compiled',\r\n debug: false,\r\n verbose: false,\r\n quiet: false,\r\n validate: false,\r\n includeMetadata: true,\r\n contextFilter,\r\n qualifierDefaults: options.qualifierDefaults,\r\n resourceTypes: options.resourceTypes,\r\n maxDistance: options.maxDistance,\r\n reduceQualifiers: options.reduceQualifiers || false\r\n };\r\n\r\n const compiler = new ResourceCompiler(infoOptions);\r\n const result = await compiler.getInfo();\r\n\r\n if (result.isFailure()) {\r\n console.error(`Error: ${result.message}`);\r\n process.exit(1);\r\n }\r\n\r\n console.log(JSON.stringify(result.value, null, 2));\r\n }\r\n\r\n /**\r\n * Handles the config command\r\n */\r\n private async _handleConfigCommand(options: IConfigCommandOptions): Promise<void> {\r\n try {\r\n // List all predefined configurations\r\n if (options.list) {\r\n console.log('Available predefined configurations:');\r\n console.log('- default');\r\n console.log('- language-priority');\r\n console.log('- territory-priority');\r\n console.log('- extended-example');\r\n return;\r\n }\r\n\r\n // Print a specific predefined configuration\r\n if (options.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\r\n if (!predefinedNames.includes(options.name as TsRes.Config.PredefinedSystemConfiguration)) {\r\n console.error(`Error: Predefined configuration '${options.name}' not found`);\r\n console.error(\r\n 'Available configurations: default, language-priority, territory-priority, extended-example'\r\n );\r\n process.exit(1);\r\n }\r\n\r\n const configResult = TsRes.Config.getPredefinedDeclaration(\r\n options.name as TsRes.Config.PredefinedSystemConfiguration\r\n );\r\n if (configResult.isFailure()) {\r\n console.error(\r\n `Error: Failed to load predefined configuration '${options.name}': ${configResult.message}`\r\n );\r\n process.exit(1);\r\n }\r\n\r\n let config = configResult.value;\r\n\r\n // Apply qualifier defaults if provided\r\n if (options.qualifierDefaults) {\r\n const tempSystemConfigResult = TsRes.Config.SystemConfiguration.create(config);\r\n if (tempSystemConfigResult.isFailure()) {\r\n console.error(`Error: Failed to create system configuration: ${tempSystemConfigResult.message}`);\r\n process.exit(1);\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(options.qualifierDefaults);\r\n if (defaultsResult.isFailure()) {\r\n console.error(`Error: Failed to parse qualifier defaults: ${defaultsResult.message}`);\r\n process.exit(1);\r\n }\r\n\r\n const updatedConfigResult = TsRes.Config.updateSystemConfigurationQualifierDefaultValues(\r\n config,\r\n defaultsResult.value\r\n );\r\n if (updatedConfigResult.isFailure()) {\r\n console.error(`Error: Failed to apply qualifier defaults: ${updatedConfigResult.message}`);\r\n process.exit(1);\r\n }\r\n\r\n config = updatedConfigResult.value;\r\n }\r\n\r\n const output = JSON.stringify(config, null, 2);\r\n\r\n if (options.output) {\r\n const fs = await import('fs').then((m) => m.promises);\r\n const path = await import('path');\r\n const outputPath = path.resolve(options.output);\r\n const outputDir = path.dirname(outputPath);\r\n\r\n await fs.mkdir(outputDir, { recursive: true });\r\n await fs.writeFile(outputPath, output, 'utf-8');\r\n console.log(`Configuration saved to: ${outputPath}`);\r\n } else {\r\n console.log(output);\r\n }\r\n return;\r\n }\r\n\r\n // Validate a configuration file\r\n if (options.validate) {\r\n const fs = await import('fs').then((m) => m.promises);\r\n const path = await import('path');\r\n\r\n const configPath = path.resolve(options.validate);\r\n const configContent = await fs.readFile(configPath, 'utf-8');\r\n const configData = JSON.parse(configContent);\r\n\r\n const configResult = TsRes.Config.Convert.systemConfiguration.convert(configData);\r\n if (configResult.isFailure()) {\r\n console.error(`Validation failed: ${configResult.message}`);\r\n process.exit(1);\r\n }\r\n\r\n console.log(`Configuration file '${configPath}' is valid`);\r\n return;\r\n }\r\n\r\n // Normalize a configuration file\r\n if (options.normalize) {\r\n const fs = await import('fs').then((m) => m.promises);\r\n const path = await import('path');\r\n\r\n const configPath = path.resolve(options.normalize);\r\n const configContent = await fs.readFile(configPath, 'utf-8');\r\n const configData = JSON.parse(configContent);\r\n\r\n const configResult = TsRes.Config.Convert.systemConfiguration.convert(configData);\r\n if (configResult.isFailure()) {\r\n console.error(`Normalization failed: ${configResult.message}`);\r\n process.exit(1);\r\n }\r\n\r\n let normalizedConfig = configResult.value;\r\n\r\n // Apply qualifier defaults if provided\r\n if (options.qualifierDefaults) {\r\n const tempSystemConfigResult = TsRes.Config.SystemConfiguration.create(normalizedConfig);\r\n if (tempSystemConfigResult.isFailure()) {\r\n console.error(`Error: Failed to create system configuration: ${tempSystemConfigResult.message}`);\r\n process.exit(1);\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(options.qualifierDefaults);\r\n if (defaultsResult.isFailure()) {\r\n console.error(`Error: Failed to parse qualifier defaults: ${defaultsResult.message}`);\r\n process.exit(1);\r\n }\r\n\r\n const updatedConfigResult = TsRes.Config.updateSystemConfigurationQualifierDefaultValues(\r\n normalizedConfig,\r\n defaultsResult.value\r\n );\r\n if (updatedConfigResult.isFailure()) {\r\n console.error(`Error: Failed to apply qualifier defaults: ${updatedConfigResult.message}`);\r\n process.exit(1);\r\n }\r\n\r\n normalizedConfig = updatedConfigResult.value;\r\n }\r\n\r\n const output = JSON.stringify(normalizedConfig, null, 2);\r\n\r\n if (options.output) {\r\n const outputPath = path.resolve(options.output);\r\n const outputDir = path.dirname(outputPath);\r\n\r\n await fs.mkdir(outputDir, { recursive: true });\r\n await fs.writeFile(outputPath, output, 'utf-8');\r\n console.log(`Normalized configuration saved to: ${outputPath}`);\r\n } else {\r\n console.log(output);\r\n }\r\n return;\r\n }\r\n\r\n // If no specific action, print default configuration\r\n const defaultResult = TsRes.Config.getPredefinedDeclaration('default');\r\n if (defaultResult.isFailure()) {\r\n console.error(`Error: Default configuration not available`);\r\n process.exit(1);\r\n }\r\n\r\n let defaultConfig = defaultResult.value;\r\n\r\n // Apply qualifier defaults if provided\r\n if (options.qualifierDefaults) {\r\n const tempSystemConfigResult = TsRes.Config.SystemConfiguration.create(defaultConfig);\r\n if (tempSystemConfigResult.isFailure()) {\r\n console.error(`Error: Failed to create system configuration: ${tempSystemConfigResult.message}`);\r\n process.exit(1);\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(options.qualifierDefaults);\r\n if (defaultsResult.isFailure()) {\r\n console.error(`Error: Failed to parse qualifier defaults: ${defaultsResult.message}`);\r\n process.exit(1);\r\n }\r\n\r\n const updatedConfigResult = TsRes.Config.updateSystemConfigurationQualifierDefaultValues(\r\n defaultConfig,\r\n defaultsResult.value\r\n );\r\n if (updatedConfigResult.isFailure()) {\r\n console.error(`Error: Failed to apply qualifier defaults: ${updatedConfigResult.message}`);\r\n process.exit(1);\r\n }\r\n\r\n defaultConfig = updatedConfigResult.value;\r\n }\r\n\r\n console.log(JSON.stringify(defaultConfig, null, 2));\r\n } catch (error) {\r\n console.error(`Error: ${error}`);\r\n process.exit(1);\r\n }\r\n }\r\n\r\n /**\r\n * Parses and validates compile options\r\n */\r\n private _parseCompileOptions(options: ICompileCommandOptions): Result<ICompileOptions> {\r\n try {\r\n const format = options.format as OutputFormat;\r\n if (!['compiled', 'source', 'js', 'ts', 'binary', 'bundle'].includes(format)) {\r\n return fail(`Invalid format: ${format}`);\r\n }\r\n\r\n // Convert JSON context to contextFilter if provided\r\n let contextFilter = options.contextFilter;\r\n if (options.context && !contextFilter) {\r\n try {\r\n const contextObj = JSON.parse(options.context);\r\n const tokens: string[] = [];\r\n for (const [key, value] of Object.entries(contextObj)) {\r\n tokens.push(`${key}=${value}`);\r\n }\r\n contextFilter = tokens.join('|');\r\n } catch (error) {\r\n return fail(`Invalid context JSON: ${error}`);\r\n }\r\n }\r\n\r\n const compileOptions: ICompileOptions = {\r\n input: options.input,\r\n output: options.output,\r\n config: options.config,\r\n contextFilter,\r\n qualifierDefaults: options.qualifierDefaults,\r\n format,\r\n debug: options.debug || false,\r\n verbose: options.verbose || false,\r\n quiet: options.quiet || false,\r\n validate: options.validate !== false,\r\n includeMetadata: options.includeMetadata || false,\r\n resourceTypes: options.resourceTypes,\r\n maxDistance: options.maxDistance,\r\n reduceQualifiers: options.reduceQualifiers || false\r\n };\r\n\r\n return succeed(compileOptions);\r\n } catch (error) {\r\n return fail(`Failed to parse options: ${error}`);\r\n }\r\n }\r\n}\r\n"]}
package/lib/compiler.d.ts CHANGED
@@ -25,6 +25,7 @@ export interface IFilteredManager {
25
25
  export interface IResourceBlob {
26
26
  resources?: TsRes.ResourceJson.Json.IResourceCollectionDecl;
27
27
  compiledCollection?: TsRes.ResourceJson.Compiled.ICompiledResourceCollection;
28
+ bundle?: TsRes.Bundle.IBundle;
28
29
  metadata?: IResourceInfo;
29
30
  }
30
31
  /**
@@ -74,6 +75,10 @@ export declare class ResourceCompiler {
74
75
  * Generates a source format blob (legacy format)
75
76
  */
76
77
  private _generateSourceBlob;
78
+ /**
79
+ * Generates a bundle blob
80
+ */
81
+ private _generateBundleBlob;
77
82
  /**
78
83
  * Generates resource information
79
84
  */
@@ -1 +1 @@
1
- {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,MAAM,EAA2B,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,KAAK,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAK5C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,sBAAsB,CAAC;IACjD,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,sBAAsB,CAAC;IAChD,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,uBAAuB,CAAC;IAC5D,kBAAkB,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,2BAA2B,CAAC;IAC7E,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,oBAAoB,CAAC,CAA0C;gBAEpD,OAAO,EAAE,eAAe;IAI3C;;OAEG;IACU,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IA0DtD;;OAEG;IACU,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;IA6BhF;;OAEG;IACU,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAqBtD;;OAEG;YACW,kBAAkB;IAmEhC;;OAEG;YACW,cAAc;IA6D5B;;OAEG;YACW,gBAAgB;IAuC9B;;OAEG;IACH,OAAO,CAAC,aAAa;IAiBrB;;OAEG;YACW,aAAa;IAY3B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAc7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAY3B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAyB7B;;OAEG;YACW,YAAY;CA2C3B"}
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,MAAM,EAA2B,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,KAAK,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAK5C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,sBAAsB,CAAC;IACjD,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,sBAAsB,CAAC;IAChD,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,SAAS,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,uBAAuB,CAAC;IAC5D,kBAAkB,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,2BAA2B,CAAC;IAC7E,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC;IAC9B,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAC3C,OAAO,CAAC,oBAAoB,CAAC,CAA0C;gBAEpD,OAAO,EAAE,eAAe;IAI3C;;OAEG;IACU,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IA0DtD;;OAEG;IACU,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;IA6BhF;;OAEG;IACU,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAqBtD;;OAEG;YACW,kBAAkB;IAmEhC;;OAEG;YACW,cAAc;IA6D5B;;OAEG;YACW,gBAAgB;IAuC9B;;OAEG;IACH,OAAO,CAAC,aAAa;IAiBrB;;OAEG;YACW,aAAa;IAc3B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAc7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAY3B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA8B3B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAyB7B;;OAEG;YACW,YAAY;CAgD3B"}
package/lib/compiler.js CHANGED
@@ -319,6 +319,9 @@ class ResourceCompiler {
319
319
  if (this._options.format === 'compiled') {
320
320
  return this._generateCompiledBlob(filtered);
321
321
  }
322
+ else if (this._options.format === 'bundle') {
323
+ return this._generateBundleBlob(filtered);
324
+ }
322
325
  else {
323
326
  return this._generateSourceBlob(filtered);
324
327
  }
@@ -354,6 +357,32 @@ class ResourceCompiler {
354
357
  return (0, ts_utils_1.succeed)(blob);
355
358
  });
356
359
  }
360
+ /**
361
+ * Generates a bundle blob
362
+ */
363
+ _generateBundleBlob(filtered) {
364
+ if (!this._systemConfiguration) {
365
+ return (0, ts_utils_1.fail)('System configuration is required for bundle generation');
366
+ }
367
+ // Create SystemConfiguration from the loaded configuration
368
+ return TsRes.Config.SystemConfiguration.create(this._systemConfiguration).onSuccess((systemConfig) => {
369
+ // Create bundle using BundleBuilder
370
+ const bundleParams = {
371
+ version: '1.0.0',
372
+ description: 'Generated bundle from ts-res-cli',
373
+ normalize: true // Use order-resilient normalization for consistent output
374
+ };
375
+ return TsRes.Bundle.BundleBuilder.create(filtered.manager, systemConfig, bundleParams).onSuccess((bundle) => {
376
+ const blob = {
377
+ bundle
378
+ };
379
+ if (this._options.includeMetadata) {
380
+ blob.metadata = this._generateResourceInfo(filtered);
381
+ }
382
+ return (0, ts_utils_1.succeed)(blob);
383
+ });
384
+ });
385
+ }
357
386
  /**
358
387
  * Generates resource information
359
388
  */
@@ -400,6 +429,11 @@ class ResourceCompiler {
400
429
  const binaryData = blob.compiledCollection || blob;
401
430
  content = JSON.stringify(binaryData);
402
431
  break;
432
+ case 'bundle':
433
+ // Bundle format outputs the complete bundle with metadata, config, and compiled resources
434
+ const bundleData = this._options.includeMetadata ? blob : blob.bundle;
435
+ content = JSON.stringify(bundleData, null, 2);
436
+ break;
403
437
  default:
404
438
  return (0, ts_utils_1.fail)(`Unsupported output format: ${this._options.format}`);
405
439
  }
@@ -1 +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"]}
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 bundle?: TsRes.Bundle.IBundle;\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 if (this._options.format === 'bundle') {\r\n return this._generateBundleBlob(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 a bundle blob\r\n */\r\n private _generateBundleBlob(filtered: IFilteredManager): Result<IResourceBlob> {\r\n if (!this._systemConfiguration) {\r\n return fail('System configuration is required for bundle generation');\r\n }\r\n\r\n // Create SystemConfiguration from the loaded configuration\r\n return TsRes.Config.SystemConfiguration.create(this._systemConfiguration).onSuccess((systemConfig) => {\r\n // Create bundle using BundleBuilder\r\n const bundleParams: TsRes.Bundle.IBundleCreateParams = {\r\n version: '1.0.0',\r\n description: 'Generated bundle from ts-res-cli',\r\n normalize: true // Use order-resilient normalization for consistent output\r\n };\r\n\r\n return TsRes.Bundle.BundleBuilder.create(filtered.manager, systemConfig, bundleParams).onSuccess(\r\n (bundle) => {\r\n const blob: IResourceBlob = {\r\n bundle\r\n };\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\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 case 'bundle':\r\n // Bundle format outputs the complete bundle with metadata, config, and compiled resources\r\n const bundleData = this._options.includeMetadata ? blob : blob.bundle;\r\n content = JSON.stringify(bundleData, null, 2);\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"]}
package/lib/options.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Output format options for resource compilation
3
3
  */
4
- export type OutputFormat = 'compiled' | 'source' | 'js' | 'ts' | 'binary';
4
+ export type OutputFormat = 'compiled' | 'source' | 'js' | 'ts' | 'binary' | 'bundle';
5
5
  /**
6
6
  * Options for resource compilation
7
7
  */
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAsBA;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,QAAQ,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,MAAM,EAAE,YAAY,CAAC;IAErB;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,eAAe,EAAE,OAAO,CAAC;IAEzB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAsBA;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,QAAQ,GAAG,IAAI,GAAG,IAAI,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAErF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,MAAM,EAAE,YAAY,CAAC;IAErB;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,eAAe,EAAE,OAAO,CAAC;IAEzB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B"}
@@ -1 +1 @@
1
- {"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG","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\n/**\r\n * Output format options for resource compilation\r\n */\r\nexport type OutputFormat = 'compiled' | 'source' | 'js' | 'ts' | 'binary';\r\n\r\n/**\r\n * Options for resource compilation\r\n */\r\nexport interface ICompileOptions {\r\n /**\r\n * Input file or directory path\r\n */\r\n input: string;\r\n\r\n /**\r\n * Output file path\r\n */\r\n output: string;\r\n\r\n /**\r\n * System configuration file path (JSON file in ISystemConfiguration format)\r\n */\r\n config?: string;\r\n\r\n /**\r\n * Context filter token (pipe-separated qualifier=value pairs, e.g., 'language=en-US|territory=US')\r\n */\r\n contextFilter?: string;\r\n\r\n /**\r\n * Qualifier default values token (pipe-separated qualifier=value pairs, e.g., 'language=en-US,en-CA|territory=US')\r\n */\r\n qualifierDefaults?: string;\r\n\r\n /**\r\n * Output format\r\n */\r\n format: OutputFormat;\r\n\r\n /**\r\n * Whether to include debug information\r\n */\r\n debug: boolean;\r\n\r\n /**\r\n * Whether to run in verbose mode\r\n */\r\n verbose: boolean;\r\n\r\n /**\r\n * Whether to run in quiet mode\r\n */\r\n quiet: boolean;\r\n\r\n /**\r\n * Whether to validate resources during compilation\r\n */\r\n validate: boolean;\r\n\r\n /**\r\n * Whether to include resource metadata in output\r\n */\r\n includeMetadata: boolean;\r\n\r\n /**\r\n * Resource type filter (e.g., 'json,other')\r\n */\r\n resourceTypes?: string;\r\n\r\n /**\r\n * Maximum distance for language matching\r\n */\r\n maxDistance?: number;\r\n\r\n /**\r\n * Whether to reduce qualifiers when filtering by context\r\n */\r\n reduceQualifiers?: boolean;\r\n}\r\n"]}
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG","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\n/**\r\n * Output format options for resource compilation\r\n */\r\nexport type OutputFormat = 'compiled' | 'source' | 'js' | 'ts' | 'binary' | 'bundle';\r\n\r\n/**\r\n * Options for resource compilation\r\n */\r\nexport interface ICompileOptions {\r\n /**\r\n * Input file or directory path\r\n */\r\n input: string;\r\n\r\n /**\r\n * Output file path\r\n */\r\n output: string;\r\n\r\n /**\r\n * System configuration file path (JSON file in ISystemConfiguration format)\r\n */\r\n config?: string;\r\n\r\n /**\r\n * Context filter token (pipe-separated qualifier=value pairs, e.g., 'language=en-US|territory=US')\r\n */\r\n contextFilter?: string;\r\n\r\n /**\r\n * Qualifier default values token (pipe-separated qualifier=value pairs, e.g., 'language=en-US,en-CA|territory=US')\r\n */\r\n qualifierDefaults?: string;\r\n\r\n /**\r\n * Output format\r\n */\r\n format: OutputFormat;\r\n\r\n /**\r\n * Whether to include debug information\r\n */\r\n debug: boolean;\r\n\r\n /**\r\n * Whether to run in verbose mode\r\n */\r\n verbose: boolean;\r\n\r\n /**\r\n * Whether to run in quiet mode\r\n */\r\n quiet: boolean;\r\n\r\n /**\r\n * Whether to validate resources during compilation\r\n */\r\n validate: boolean;\r\n\r\n /**\r\n * Whether to include resource metadata in output\r\n */\r\n includeMetadata: boolean;\r\n\r\n /**\r\n * Resource type filter (e.g., 'json,other')\r\n */\r\n resourceTypes?: string;\r\n\r\n /**\r\n * Maximum distance for language matching\r\n */\r\n maxDistance?: number;\r\n\r\n /**\r\n * Whether to reduce qualifiers when filtering by context\r\n */\r\n reduceQualifiers?: boolean;\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fgv/ts-res-cli",
3
- "version": "5.0.0-8",
3
+ "version": "5.0.0-9",
4
4
  "description": "Command-line interface for ts-res resource compilation and management",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -18,11 +18,11 @@
18
18
  "license": "MIT",
19
19
  "dependencies": {
20
20
  "commander": "^11.0.0",
21
- "@fgv/ts-res": "5.0.0-8",
22
- "@fgv/ts-extras": "5.0.0-8",
23
- "@fgv/ts-json": "5.0.0-8",
24
- "@fgv/ts-utils": "5.0.0-8",
25
- "@fgv/ts-json-base": "5.0.0-8"
21
+ "@fgv/ts-res": "5.0.0-9",
22
+ "@fgv/ts-utils": "5.0.0-9",
23
+ "@fgv/ts-json": "5.0.0-9",
24
+ "@fgv/ts-json-base": "5.0.0-9",
25
+ "@fgv/ts-extras": "5.0.0-9"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@rushstack/heft": "~0.74.0",
@@ -37,7 +37,7 @@
37
37
  "jest": "^29.7.0",
38
38
  "ts-jest": "^29.4.0",
39
39
  "typescript": "^5.7.3",
40
- "@fgv/ts-utils-jest": "5.0.0-8"
40
+ "@fgv/ts-utils-jest": "5.0.0-9"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "typescript": "^5.7.3"
package/src/cli.ts CHANGED
@@ -133,7 +133,7 @@ export class TsResCliApp {
133
133
  '--qualifier-defaults <token>',
134
134
  'Qualifier default values token (pipe-separated, e.g., "language=en-US,en-CA|territory=US")'
135
135
  )
136
- .option('-f, --format <format>', 'Output format', 'compiled')
136
+ .option('-f, --format <format>', 'Output format (compiled, source, js, ts, binary, bundle)', 'compiled')
137
137
  .option('--debug', 'Include debug information', false)
138
138
  .option('-v, --verbose', 'Verbose output', false)
139
139
  .option('-q, --quiet', 'Quiet output', false)
@@ -563,7 +563,7 @@ export class TsResCliApp {
563
563
  private _parseCompileOptions(options: ICompileCommandOptions): Result<ICompileOptions> {
564
564
  try {
565
565
  const format = options.format as OutputFormat;
566
- if (!['compiled', 'source', 'js', 'ts', 'binary'].includes(format)) {
566
+ if (!['compiled', 'source', 'js', 'ts', 'binary', 'bundle'].includes(format)) {
567
567
  return fail(`Invalid format: ${format}`);
568
568
  }
569
569
 
package/src/compiler.ts CHANGED
@@ -53,6 +53,7 @@ export interface IFilteredManager {
53
53
  export interface IResourceBlob {
54
54
  resources?: TsRes.ResourceJson.Json.IResourceCollectionDecl;
55
55
  compiledCollection?: TsRes.ResourceJson.Compiled.ICompiledResourceCollection;
56
+ bundle?: TsRes.Bundle.IBundle;
56
57
  metadata?: IResourceInfo;
57
58
  }
58
59
 
@@ -387,6 +388,8 @@ export class ResourceCompiler {
387
388
  try {
388
389
  if (this._options.format === 'compiled') {
389
390
  return this._generateCompiledBlob(filtered);
391
+ } else if (this._options.format === 'bundle') {
392
+ return this._generateBundleBlob(filtered);
390
393
  } else {
391
394
  return this._generateSourceBlob(filtered);
392
395
  }
@@ -427,6 +430,39 @@ export class ResourceCompiler {
427
430
  });
428
431
  }
429
432
 
433
+ /**
434
+ * Generates a bundle blob
435
+ */
436
+ private _generateBundleBlob(filtered: IFilteredManager): Result<IResourceBlob> {
437
+ if (!this._systemConfiguration) {
438
+ return fail('System configuration is required for bundle generation');
439
+ }
440
+
441
+ // Create SystemConfiguration from the loaded configuration
442
+ return TsRes.Config.SystemConfiguration.create(this._systemConfiguration).onSuccess((systemConfig) => {
443
+ // Create bundle using BundleBuilder
444
+ const bundleParams: TsRes.Bundle.IBundleCreateParams = {
445
+ version: '1.0.0',
446
+ description: 'Generated bundle from ts-res-cli',
447
+ normalize: true // Use order-resilient normalization for consistent output
448
+ };
449
+
450
+ return TsRes.Bundle.BundleBuilder.create(filtered.manager, systemConfig, bundleParams).onSuccess(
451
+ (bundle) => {
452
+ const blob: IResourceBlob = {
453
+ bundle
454
+ };
455
+
456
+ if (this._options.includeMetadata) {
457
+ blob.metadata = this._generateResourceInfo(filtered);
458
+ }
459
+
460
+ return succeed(blob);
461
+ }
462
+ );
463
+ });
464
+ }
465
+
430
466
  /**
431
467
  * Generates resource information
432
468
  */
@@ -491,6 +527,11 @@ export class ResourceCompiler {
491
527
  const binaryData = blob.compiledCollection || blob;
492
528
  content = JSON.stringify(binaryData);
493
529
  break;
530
+ case 'bundle':
531
+ // Bundle format outputs the complete bundle with metadata, config, and compiled resources
532
+ const bundleData = this._options.includeMetadata ? blob : blob.bundle;
533
+ content = JSON.stringify(bundleData, null, 2);
534
+ break;
494
535
  default:
495
536
  return fail(`Unsupported output format: ${this._options.format}`);
496
537
  }
package/src/options.ts CHANGED
@@ -23,7 +23,7 @@
23
23
  /**
24
24
  * Output format options for resource compilation
25
25
  */
26
- export type OutputFormat = 'compiled' | 'source' | 'js' | 'ts' | 'binary';
26
+ export type OutputFormat = 'compiled' | 'source' | 'js' | 'ts' | 'binary' | 'bundle';
27
27
 
28
28
  /**
29
29
  * Options for resource compilation
@@ -209,6 +209,54 @@ describe('CLI Integration Tests', () => {
209
209
  expect(outputContent).toMatch(/ as const;$/);
210
210
  });
211
211
 
212
+ test('compiles resources to bundle format', async () => {
213
+ const bundleOutputFile = path.join(tempDir, 'compiled.bundle.json');
214
+ const result = await runCli([
215
+ 'compile',
216
+ '--input',
217
+ inputFile,
218
+ '--output',
219
+ bundleOutputFile,
220
+ '--format',
221
+ 'bundle'
222
+ ]);
223
+
224
+ expect(result.exitCode).toBe(0);
225
+
226
+ const outputContent = await fs.readFile(bundleOutputFile, 'utf-8');
227
+ const bundle = JSON.parse(outputContent);
228
+
229
+ // Bundle should have the expected structure
230
+ expect(bundle).toHaveProperty('metadata');
231
+ expect(bundle).toHaveProperty('config');
232
+ expect(bundle).toHaveProperty('compiledCollection');
233
+
234
+ // Metadata should have checksum and date
235
+ expect(bundle.metadata).toHaveProperty('checksum');
236
+ expect(bundle.metadata).toHaveProperty('dateBuilt');
237
+
238
+ // Config should be a valid system configuration
239
+ expect(bundle.config).toHaveProperty('qualifierTypes');
240
+ expect(bundle.config).toHaveProperty('qualifiers');
241
+ expect(bundle.config).toHaveProperty('resourceTypes');
242
+
243
+ // Compiled collection should have resources
244
+ expect(bundle.compiledCollection).toHaveProperty('resources');
245
+ expect(Array.isArray(bundle.compiledCollection.resources)).toBe(true);
246
+ expect(bundle.compiledCollection.resources.length).toBeGreaterThan(0);
247
+
248
+ // Check that resources include our test data
249
+ const resourceIds = bundle.compiledCollection.resources.map((r: any) => r.id);
250
+ expect(resourceIds).toContain('resources.app.title');
251
+ expect(resourceIds).toContain('resources.messages.welcome');
252
+
253
+ // Verify bundle can be loaded back into a resource manager
254
+ expect(TsRes.Bundle.Convert.bundle.convert(bundle)).toSucceedAndSatisfy((validatedBundle) => {
255
+ expect(TsRes.Bundle.BundleLoader.createManagerFromBundle({ bundle: validatedBundle })).toSucceed();
256
+ return true;
257
+ });
258
+ });
259
+
212
260
  test('compiles with context filtering', async () => {
213
261
  const result = await runCli([
214
262
  'compile',