@fgv/ts-res-cli 5.0.1-0 → 5.0.1-10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/lib/cli.d.ts +40 -0
  2. package/lib/cli.js +497 -0
  3. package/package.json +16 -19
package/lib/cli.d.ts CHANGED
@@ -28,13 +28,53 @@ export declare class TsResCliApp {
28
28
  * Handles the config command
29
29
  */
30
30
  private _handleConfigCommand;
31
+ /**
32
+ * Handles the delta command
33
+ */
34
+ private _handleDeltaCommand;
31
35
  /**
32
36
  * Handles the archive command
33
37
  */
34
38
  private _handleArchiveCommand;
39
+ /**
40
+ * Parses and validates delta options
41
+ */
42
+ private _parseDeltaOptions;
35
43
  /**
36
44
  * Parses and validates compile options
37
45
  */
38
46
  private _parseCompileOptions;
47
+ /**
48
+ * Generates delta between baseline and target resources
49
+ */
50
+ private _generateDelta;
51
+ /**
52
+ * Loads system configuration (reused from ResourceCompiler pattern)
53
+ */
54
+ private _loadSystemConfiguration;
55
+ /**
56
+ * Creates a resource manager from a path (reused from ResourceCompiler pattern)
57
+ */
58
+ private _createResourceManager;
59
+ /**
60
+ * Imports resources from a file path (reused from ResourceCompiler pattern)
61
+ */
62
+ private _importResourcesFromPath;
63
+ /**
64
+ * Creates a resource resolver from a resource manager and system configuration
65
+ */
66
+ private _createResourceResolver;
67
+ /**
68
+ * Generates output blob for delta resources
69
+ */
70
+ private _generateDeltaBlob;
71
+ /**
72
+ * Generates resource information for delta output
73
+ */
74
+ private _generateDeltaResourceInfo;
75
+ /**
76
+ * Writes delta output to file
77
+ */
78
+ private _writeDeltaOutput;
39
79
  }
40
80
  //# sourceMappingURL=cli.d.ts.map
package/lib/cli.js CHANGED
@@ -153,6 +153,24 @@ class TsResCliApp {
153
153
  .action(async (options) => {
154
154
  await this._handleArchiveCommand(options);
155
155
  });
156
+ this._program
157
+ .command('delta')
158
+ .description('Generate delta between baseline and target resources')
159
+ .requiredOption('--baseline <path>', 'Baseline resource file or directory path')
160
+ .requiredOption('--target <path>', 'Target resource file or directory path')
161
+ .requiredOption('-o, --output <path>', 'Output file path')
162
+ .option('--config <name|path>', 'Predefined configuration name or system configuration file path (JSON, ISystemConfiguration format)')
163
+ .option('--context-filter <token>', 'Context filter token (pipe-separated, e.g., "language=en-US|territory=US")')
164
+ .option('--qualifier-defaults <token>', 'Qualifier default values token (pipe-separated, e.g., "language=en-US,en-CA|territory=US")')
165
+ .option('--resource-ids <ids>', 'Comma-separated list of specific resource IDs to include in delta generation')
166
+ .option('--skip-unchanged', 'Skip resources that have not changed between baseline and target', true)
167
+ .option('-f, --format <format>', 'Output format (compiled, source, js, ts, binary, bundle)', 'compiled')
168
+ .option('-v, --verbose', 'Verbose output', false)
169
+ .option('-q, --quiet', 'Quiet output', false)
170
+ .option('--include-metadata', 'Include resource metadata in output', false)
171
+ .action(async (options) => {
172
+ await this._handleDeltaCommand(options);
173
+ });
156
174
  }
157
175
  /**
158
176
  * Handles the compile command
@@ -424,6 +442,24 @@ class TsResCliApp {
424
442
  process.exit(1);
425
443
  }
426
444
  }
445
+ /**
446
+ * Handles the delta command
447
+ */
448
+ async _handleDeltaCommand(options) {
449
+ const deltaOptions = this._parseDeltaOptions(options);
450
+ if (deltaOptions.isFailure()) {
451
+ console.error(`Error: ${deltaOptions.message}`);
452
+ process.exit(1);
453
+ }
454
+ const result = await this._generateDelta(deltaOptions.value);
455
+ if (result.isFailure()) {
456
+ console.error(`Error: ${result.message}`);
457
+ process.exit(1);
458
+ }
459
+ if (!options.quiet) {
460
+ console.log(`Successfully generated delta to ${options.output}`);
461
+ }
462
+ }
427
463
  /**
428
464
  * Handles the archive command
429
465
  */
@@ -479,6 +515,47 @@ class TsResCliApp {
479
515
  process.exit(1);
480
516
  }
481
517
  }
518
+ /**
519
+ * Parses and validates delta options
520
+ */
521
+ _parseDeltaOptions(options) {
522
+ var _a;
523
+ try {
524
+ const format = options.format;
525
+ if (!['compiled', 'source', 'js', 'ts', 'binary', 'bundle'].includes(format)) {
526
+ return (0, ts_utils_1.fail)(`Invalid format: ${format}`);
527
+ }
528
+ // Parse resource IDs if provided
529
+ let resourceIds;
530
+ if (options.resourceIds) {
531
+ resourceIds = options.resourceIds
532
+ .split(',')
533
+ .map((id) => id.trim())
534
+ .filter((id) => id.length > 0);
535
+ if (resourceIds.length === 0) {
536
+ return (0, ts_utils_1.fail)('Resource IDs list cannot be empty');
537
+ }
538
+ }
539
+ const deltaOptions = {
540
+ baseline: options.baseline,
541
+ target: options.target,
542
+ output: options.output,
543
+ config: options.config,
544
+ contextFilter: options.contextFilter,
545
+ qualifierDefaults: options.qualifierDefaults,
546
+ resourceIds,
547
+ skipUnchanged: (_a = options.skipUnchanged) !== null && _a !== void 0 ? _a : true,
548
+ format,
549
+ verbose: options.verbose || false,
550
+ quiet: options.quiet || false,
551
+ includeMetadata: options.includeMetadata || false
552
+ };
553
+ return (0, ts_utils_1.succeed)(deltaOptions);
554
+ }
555
+ catch (error) {
556
+ return (0, ts_utils_1.fail)(`Failed to parse delta options: ${error}`);
557
+ }
558
+ }
482
559
  /**
483
560
  * Parses and validates compile options
484
561
  */
@@ -525,6 +602,426 @@ class TsResCliApp {
525
602
  return (0, ts_utils_1.fail)(`Failed to parse options: ${error}`);
526
603
  }
527
604
  }
605
+ /**
606
+ * Generates delta between baseline and target resources
607
+ */
608
+ async _generateDelta(options) {
609
+ try {
610
+ if (options.verbose) {
611
+ console.error('Starting delta generation...');
612
+ console.error(`Baseline: ${options.baseline}`);
613
+ console.error(`Target: ${options.target}`);
614
+ console.error(`Output: ${options.output}`);
615
+ }
616
+ // Load system configuration
617
+ const config = await this._loadSystemConfiguration(options.config, options.verbose);
618
+ if (config.isFailure()) {
619
+ return (0, ts_utils_1.fail)(`Failed to load configuration: ${config.message}`);
620
+ }
621
+ if (options.verbose) {
622
+ console.error('Configuration loaded successfully');
623
+ }
624
+ // Create resource managers for baseline and target
625
+ const baselineManager = await this._createResourceManager(config.value, options.baseline, options.qualifierDefaults, options.verbose);
626
+ if (baselineManager.isFailure()) {
627
+ return (0, ts_utils_1.fail)(`Failed to load baseline resources: ${baselineManager.message}`);
628
+ }
629
+ const targetManager = await this._createResourceManager(config.value, options.target, options.qualifierDefaults, options.verbose);
630
+ if (targetManager.isFailure()) {
631
+ return (0, ts_utils_1.fail)(`Failed to load target resources: ${targetManager.message}`);
632
+ }
633
+ if (options.verbose) {
634
+ console.error(`Baseline loaded: ${baselineManager.value.numResources} resources, ${baselineManager.value.numCandidates} candidates`);
635
+ console.error(`Target loaded: ${targetManager.value.numResources} resources, ${targetManager.value.numCandidates} candidates`);
636
+ }
637
+ // Create resource resolvers
638
+ const baselineResolver = await this._createResourceResolver(baselineManager.value, options.contextFilter, options.verbose, config.value);
639
+ if (baselineResolver.isFailure()) {
640
+ return (0, ts_utils_1.fail)(`Failed to create baseline resolver: ${baselineResolver.message}`);
641
+ }
642
+ const targetResolver = await this._createResourceResolver(targetManager.value, options.contextFilter, options.verbose, config.value);
643
+ if (targetResolver.isFailure()) {
644
+ return (0, ts_utils_1.fail)(`Failed to create target resolver: ${targetResolver.message}`);
645
+ }
646
+ // Create delta generator
647
+ const deltaGenerator = TsRes.Resources.DeltaGenerator.create({
648
+ baselineResolver: baselineResolver.value,
649
+ deltaResolver: targetResolver.value,
650
+ resourceManager: baselineManager.value,
651
+ logger: options.verbose ? new ts_utils_1.Logging.ConsoleLogger() : undefined
652
+ });
653
+ if (deltaGenerator.isFailure()) {
654
+ return (0, ts_utils_1.fail)(`Failed to create delta generator: ${deltaGenerator.message}`);
655
+ }
656
+ // Parse context filter for delta generation options
657
+ let context;
658
+ if (options.contextFilter) {
659
+ const contextTokens = new TsRes.Context.ContextTokens(baselineManager.value.qualifiers);
660
+ const contextResult = contextTokens.contextTokenToPartialContext(options.contextFilter);
661
+ if (contextResult.isFailure()) {
662
+ return (0, ts_utils_1.fail)(`Failed to parse context filter: ${contextResult.message}`);
663
+ }
664
+ context = contextResult.value;
665
+ }
666
+ // Generate delta
667
+ const deltaOptions = {
668
+ context,
669
+ resourceIds: options.resourceIds,
670
+ skipUnchanged: options.skipUnchanged
671
+ };
672
+ if (options.verbose) {
673
+ console.error('Generating delta...');
674
+ }
675
+ const deltaResult = deltaGenerator.value.generate(deltaOptions);
676
+ if (deltaResult.isFailure()) {
677
+ return (0, ts_utils_1.fail)(`Delta generation failed: ${deltaResult.message}`);
678
+ }
679
+ const deltaManager = deltaResult.value;
680
+ if (options.verbose) {
681
+ console.error(`Delta generated: ${deltaManager.numResources} resources, ${deltaManager.numCandidates} candidates`);
682
+ }
683
+ // Generate output blob
684
+ const blob = await this._generateDeltaBlob(deltaManager, options, config.value);
685
+ if (blob.isFailure()) {
686
+ return (0, ts_utils_1.fail)(`Failed to generate output blob: ${blob.message}`);
687
+ }
688
+ // Write output
689
+ const writeResult = await this._writeDeltaOutput(blob.value, options);
690
+ if (writeResult.isFailure()) {
691
+ return (0, ts_utils_1.fail)(`Failed to write output: ${writeResult.message}`);
692
+ }
693
+ if (options.verbose) {
694
+ console.error(`Delta output written to: ${options.output}`);
695
+ }
696
+ return (0, ts_utils_1.succeed)(undefined);
697
+ }
698
+ catch (error) {
699
+ return (0, ts_utils_1.fail)(`Delta generation failed: ${error}`);
700
+ }
701
+ }
702
+ /**
703
+ * Loads system configuration (reused from ResourceCompiler pattern)
704
+ */
705
+ async _loadSystemConfiguration(configOption, verbose) {
706
+ try {
707
+ if (configOption) {
708
+ // Check if it's a predefined configuration name
709
+ const predefinedNames = [
710
+ 'default',
711
+ 'language-priority',
712
+ 'territory-priority',
713
+ 'extended-example'
714
+ ];
715
+ if (predefinedNames.includes(configOption)) {
716
+ const predefinedResult = TsRes.Config.getPredefinedDeclaration(configOption);
717
+ if (predefinedResult.isSuccess()) {
718
+ if (verbose) {
719
+ console.error(`Using predefined configuration: ${predefinedResult.value.name}`);
720
+ }
721
+ return (0, ts_utils_1.succeed)(predefinedResult.value);
722
+ }
723
+ }
724
+ // Try to load as file path
725
+ try {
726
+ const path = await Promise.resolve().then(() => __importStar(require('path')));
727
+ const fs = await Promise.resolve().then(() => __importStar(require('fs'))).then((m) => m.promises);
728
+ const configPath = path.resolve(configOption);
729
+ const configContent = await fs.readFile(configPath, 'utf-8');
730
+ const configData = JSON.parse(configContent);
731
+ const configResult = TsRes.Config.Convert.systemConfiguration.convert(configData);
732
+ if (configResult.isFailure()) {
733
+ return (0, ts_utils_1.fail)(`Invalid configuration file: ${configResult.message}`);
734
+ }
735
+ if (verbose) {
736
+ console.error(`Using custom configuration: ${configResult.value.name}`);
737
+ }
738
+ return (0, ts_utils_1.succeed)(configResult.value);
739
+ }
740
+ catch (fileError) {
741
+ return (0, ts_utils_1.fail)(`Configuration '${configOption}' is not a predefined configuration name and failed to load as file: ${fileError}`);
742
+ }
743
+ }
744
+ else {
745
+ // Use default configuration
746
+ const defaultResult = TsRes.Config.getPredefinedDeclaration('default');
747
+ if (defaultResult.isSuccess()) {
748
+ if (verbose) {
749
+ console.error(`Using default configuration: ${defaultResult.value.name}`);
750
+ }
751
+ return (0, ts_utils_1.succeed)(defaultResult.value);
752
+ }
753
+ else {
754
+ return (0, ts_utils_1.fail)('Failed to load default configuration');
755
+ }
756
+ }
757
+ }
758
+ catch (error) {
759
+ return (0, ts_utils_1.fail)(`Failed to load system configuration: ${error}`);
760
+ }
761
+ }
762
+ /**
763
+ * Creates a resource manager from a path (reused from ResourceCompiler pattern)
764
+ */
765
+ async _createResourceManager(systemConfig, inputPath, qualifierDefaults, verbose) {
766
+ try {
767
+ // Parse qualifier defaults if provided
768
+ let qualifierDefaultValues;
769
+ if (qualifierDefaults) {
770
+ const tempSystemConfigResult = TsRes.Config.SystemConfiguration.create(systemConfig);
771
+ if (tempSystemConfigResult.isFailure()) {
772
+ return (0, ts_utils_1.fail)(`Failed to create temporary system configuration: ${tempSystemConfigResult.message}`);
773
+ }
774
+ const tokens = new TsRes.Qualifiers.QualifierDefaultValueTokens(tempSystemConfigResult.value.qualifiers);
775
+ const defaultsResult = tokens.qualifierDefaultValuesTokenToDecl(qualifierDefaults);
776
+ if (defaultsResult.isFailure()) {
777
+ return (0, ts_utils_1.fail)(`Failed to parse qualifier defaults: ${defaultsResult.message}`);
778
+ }
779
+ qualifierDefaultValues = defaultsResult.value;
780
+ }
781
+ // Create system configuration
782
+ const systemConfigResult = TsRes.Config.SystemConfiguration.create(systemConfig, qualifierDefaultValues ? { qualifierDefaultValues } : undefined);
783
+ if (systemConfigResult.isFailure()) {
784
+ return (0, ts_utils_1.fail)(`Failed to create system configuration: ${systemConfigResult.message}`);
785
+ }
786
+ const config = systemConfigResult.value;
787
+ // Create resource manager
788
+ const manager = TsRes.Resources.ResourceManagerBuilder.create({
789
+ qualifiers: config.qualifiers,
790
+ resourceTypes: config.resourceTypes
791
+ });
792
+ if (manager.isFailure()) {
793
+ return (0, ts_utils_1.fail)(`Failed to create resource manager: ${manager.message}`);
794
+ }
795
+ // Import resources from path
796
+ const importResult = await this._importResourcesFromPath(manager.value, inputPath, verbose);
797
+ if (importResult.isFailure()) {
798
+ return (0, ts_utils_1.fail)(`Failed to import resources from ${inputPath}: ${importResult.message}`);
799
+ }
800
+ return (0, ts_utils_1.succeed)(manager.value);
801
+ }
802
+ catch (error) {
803
+ return (0, ts_utils_1.fail)(`Failed to create resource manager: ${error}`);
804
+ }
805
+ }
806
+ /**
807
+ * Imports resources from a file path (reused from ResourceCompiler pattern)
808
+ */
809
+ async _importResourcesFromPath(manager, inputPath, verbose) {
810
+ try {
811
+ const path = await Promise.resolve().then(() => __importStar(require('path')));
812
+ const { FileTree } = await Promise.resolve().then(() => __importStar(require('@fgv/ts-json-base')));
813
+ const resolvedPath = path.resolve(inputPath);
814
+ // Create FileTree for file system operations
815
+ const fileTree = FileTree.forFilesystem();
816
+ if (fileTree.isFailure()) {
817
+ return (0, ts_utils_1.fail)(`Failed to create file tree: ${fileTree.message}`);
818
+ }
819
+ // Create ImportManager
820
+ const importManager = TsRes.Import.ImportManager.create({
821
+ resources: manager,
822
+ fileTree: fileTree.value
823
+ });
824
+ if (importManager.isFailure()) {
825
+ return (0, ts_utils_1.fail)(`Failed to create import manager: ${importManager.message}`);
826
+ }
827
+ // Import resources
828
+ if (verbose) {
829
+ console.error(`Importing resources from: ${resolvedPath}`);
830
+ }
831
+ const importResult = importManager.value.importFromFileSystem(resolvedPath);
832
+ if (importResult.isFailure()) {
833
+ return (0, ts_utils_1.fail)(`Failed to import from ${resolvedPath}: ${importResult.message}`);
834
+ }
835
+ if (verbose) {
836
+ console.error(`Successfully imported resources from: ${resolvedPath}`);
837
+ }
838
+ return (0, ts_utils_1.succeed)(undefined);
839
+ }
840
+ catch (error) {
841
+ return (0, ts_utils_1.fail)(`Failed to import resources: ${error}`);
842
+ }
843
+ }
844
+ /**
845
+ * Creates a resource resolver from a resource manager and system configuration
846
+ */
847
+ async _createResourceResolver(manager, contextFilter, verbose, systemConfig) {
848
+ try {
849
+ // Apply context filtering if specified
850
+ let finalManager = manager;
851
+ if (contextFilter) {
852
+ const contextTokens = new TsRes.Context.ContextTokens(manager.qualifiers);
853
+ const contextResult = contextTokens.contextTokenToPartialContext(contextFilter);
854
+ if (contextResult.isFailure()) {
855
+ return (0, ts_utils_1.fail)(`Failed to parse context filter: ${contextResult.message}`);
856
+ }
857
+ const filteredManagerResult = manager.clone({
858
+ filterForContext: contextResult.value,
859
+ reduceQualifiers: false // Don't reduce qualifiers for delta generation
860
+ });
861
+ if (filteredManagerResult.isFailure()) {
862
+ return (0, ts_utils_1.fail)(`Failed to apply context filter: ${filteredManagerResult.message}`);
863
+ }
864
+ finalManager = filteredManagerResult.value;
865
+ if (verbose) {
866
+ console.error(`After context filtering: ${finalManager.numResources} resources, ${finalManager.numCandidates} candidates`);
867
+ }
868
+ }
869
+ // Build the manager to create the resolver
870
+ const builtManager = finalManager.build();
871
+ if (builtManager.isFailure()) {
872
+ return (0, ts_utils_1.fail)(`Failed to build resource manager: ${builtManager.message}`);
873
+ }
874
+ // Create qualifier types from system config or use default
875
+ const qualifierTypesResult = systemConfig
876
+ ? TsRes.Config.SystemConfiguration.create(systemConfig).onSuccess((config) => (0, ts_utils_1.succeed)(config.qualifierTypes))
877
+ : TsRes.QualifierTypes.QualifierTypeCollector.create({
878
+ qualifierTypes: [
879
+ TsRes.QualifierTypes.LanguageQualifierType.create().orThrow(),
880
+ TsRes.QualifierTypes.TerritoryQualifierType.create().orThrow()
881
+ ]
882
+ });
883
+ if (qualifierTypesResult.isFailure()) {
884
+ return (0, ts_utils_1.fail)(`Failed to create qualifier types: ${qualifierTypesResult.message}`);
885
+ }
886
+ // Create context provider - use empty context for default
887
+ const contextProvider = TsRes.Runtime.ValidatingSimpleContextQualifierProvider.create({
888
+ qualifiers: finalManager.qualifiers,
889
+ qualifierValues: {} // Empty context for most general resolution
890
+ });
891
+ if (contextProvider.isFailure()) {
892
+ return (0, ts_utils_1.fail)(`Failed to create context provider: ${contextProvider.message}`);
893
+ }
894
+ // Create resolver with required parameters
895
+ const resolver = TsRes.Runtime.ResourceResolver.create({
896
+ resourceManager: builtManager.value,
897
+ qualifierTypes: qualifierTypesResult.value,
898
+ contextQualifierProvider: contextProvider.value
899
+ });
900
+ if (resolver.isFailure()) {
901
+ return (0, ts_utils_1.fail)(`Failed to create resource resolver: ${resolver.message}`);
902
+ }
903
+ return (0, ts_utils_1.succeed)(resolver.value);
904
+ }
905
+ catch (error) {
906
+ return (0, ts_utils_1.fail)(`Failed to create resource resolver: ${error}`);
907
+ }
908
+ }
909
+ /**
910
+ * Generates output blob for delta resources
911
+ */
912
+ async _generateDeltaBlob(deltaManager, options, systemConfig) {
913
+ try {
914
+ if (options.format === 'compiled') {
915
+ return deltaManager.getCompiledResourceCollection().onSuccess((compiled) => {
916
+ const blob = {
917
+ compiledCollection: compiled
918
+ };
919
+ if (options.includeMetadata) {
920
+ blob.metadata = this._generateDeltaResourceInfo(deltaManager);
921
+ }
922
+ return (0, ts_utils_1.succeed)(blob);
923
+ });
924
+ }
925
+ else if (options.format === 'bundle') {
926
+ // Create bundle using BundleBuilder
927
+ const systemConfigResult = TsRes.Config.SystemConfiguration.create(systemConfig);
928
+ if (systemConfigResult.isFailure()) {
929
+ return (0, ts_utils_1.fail)(`Failed to create system configuration for bundle: ${systemConfigResult.message}`);
930
+ }
931
+ const bundleParams = {
932
+ version: '1.0.0',
933
+ description: 'Generated delta bundle from ts-res-cli',
934
+ normalize: true
935
+ };
936
+ return TsRes.Bundle.BundleBuilder.create(deltaManager, systemConfigResult.value, bundleParams).onSuccess((bundle) => {
937
+ const blob = {
938
+ bundle
939
+ };
940
+ if (options.includeMetadata) {
941
+ blob.metadata = this._generateDeltaResourceInfo(deltaManager);
942
+ }
943
+ return (0, ts_utils_1.succeed)(blob);
944
+ });
945
+ }
946
+ else {
947
+ // Source format
948
+ return deltaManager.getResourceCollectionDecl().onSuccess((resources) => {
949
+ const blob = {
950
+ resources
951
+ };
952
+ if (options.includeMetadata) {
953
+ blob.metadata = this._generateDeltaResourceInfo(deltaManager);
954
+ }
955
+ return (0, ts_utils_1.succeed)(blob);
956
+ });
957
+ }
958
+ }
959
+ catch (error) {
960
+ return (0, ts_utils_1.fail)(`Failed to generate delta blob: ${error}`);
961
+ }
962
+ }
963
+ /**
964
+ * Generates resource information for delta output
965
+ */
966
+ _generateDeltaResourceInfo(deltaManager) {
967
+ const resourceTypes = Array.from(new Set(deltaManager
968
+ .getAllCandidates()
969
+ .map((c) => { var _a; return (_a = c.resourceType) === null || _a === void 0 ? void 0 : _a.key; })
970
+ .filter(Boolean)));
971
+ const qualifiers = Array.from(deltaManager.qualifiers.keys());
972
+ return {
973
+ totalResources: deltaManager.numResources,
974
+ totalCandidates: deltaManager.numCandidates,
975
+ resourceTypes,
976
+ qualifiers
977
+ };
978
+ }
979
+ /**
980
+ * Writes delta output to file
981
+ */
982
+ async _writeDeltaOutput(blob, options) {
983
+ try {
984
+ const path = await Promise.resolve().then(() => __importStar(require('path')));
985
+ const fs = await Promise.resolve().then(() => __importStar(require('fs'))).then((m) => m.promises);
986
+ const outputPath = path.resolve(options.output);
987
+ const outputDir = path.dirname(outputPath);
988
+ // Ensure output directory exists
989
+ await fs.mkdir(outputDir, { recursive: true });
990
+ let content;
991
+ switch (options.format) {
992
+ case 'compiled':
993
+ const compiledData = options.includeMetadata ? blob : blob.compiledCollection;
994
+ content = JSON.stringify(compiledData, null, 2);
995
+ break;
996
+ case 'source':
997
+ content = JSON.stringify(blob, null, 2);
998
+ break;
999
+ case 'js':
1000
+ const jsData = blob.compiledCollection || blob;
1001
+ content = `module.exports = ${JSON.stringify(jsData, null, 2)};`;
1002
+ break;
1003
+ case 'ts':
1004
+ const tsData = blob.compiledCollection || blob;
1005
+ content = `export const resources = ${JSON.stringify(tsData, null, 2)} as const;`;
1006
+ break;
1007
+ case 'binary':
1008
+ const binaryData = blob.compiledCollection || blob;
1009
+ content = JSON.stringify(binaryData);
1010
+ break;
1011
+ case 'bundle':
1012
+ const bundleData = options.includeMetadata ? blob : blob.bundle;
1013
+ content = JSON.stringify(bundleData, null, 2);
1014
+ break;
1015
+ default:
1016
+ return (0, ts_utils_1.fail)(`Unsupported output format: ${options.format}`);
1017
+ }
1018
+ await fs.writeFile(outputPath, content, 'utf-8');
1019
+ return (0, ts_utils_1.succeed)(undefined);
1020
+ }
1021
+ catch (error) {
1022
+ return (0, ts_utils_1.fail)(`Failed to write delta output: ${error}`);
1023
+ }
1024
+ }
528
1025
  }
529
1026
  exports.TsResCliApp = TsResCliApp;
530
1027
  //# sourceMappingURL=cli.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fgv/ts-res-cli",
3
- "version": "5.0.1-0",
3
+ "version": "5.0.1-10",
4
4
  "description": "Command-line interface for ts-res resource compilation and management",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -18,30 +18,27 @@
18
18
  "license": "MIT",
19
19
  "dependencies": {
20
20
  "commander": "^11.0.0",
21
- "@fgv/ts-res": "5.0.1-0",
22
- "@fgv/ts-utils": "5.0.1-0",
23
- "@fgv/ts-extras": "5.0.1-0",
24
- "@fgv/ts-json": "5.0.1-0",
25
- "@fgv/ts-json-base": "5.0.1-0"
21
+ "@fgv/ts-res": "5.0.1-10",
22
+ "@fgv/ts-utils": "5.0.1-10",
23
+ "@fgv/ts-json": "5.0.1-10",
24
+ "@fgv/ts-extras": "5.0.1-10",
25
+ "@fgv/ts-json-base": "5.0.1-10"
26
26
  },
27
27
  "devDependencies": {
28
- "@rushstack/heft": "0.74.4",
29
- "@rushstack/heft-node-rig": "2.9.5",
30
- "@rushstack/eslint-config": "4.4.0",
28
+ "@rushstack/heft": "1.1.3",
29
+ "@rushstack/heft-node-rig": "2.11.4",
30
+ "@rushstack/eslint-config": "4.5.3",
31
31
  "@types/heft-jest": "1.0.6",
32
32
  "@types/jest": "^29.5.14",
33
33
  "@types/node": "^20.14.9",
34
- "@typescript-eslint/eslint-plugin": "^8.42.0",
35
- "@typescript-eslint/parser": "^8.42.0",
36
- "eslint": "^9.35.0",
34
+ "@typescript-eslint/eslint-plugin": "^8.46.2",
35
+ "@typescript-eslint/parser": "^8.46.2",
36
+ "eslint": "^9.39.0",
37
37
  "jest": "^29.7.0",
38
- "ts-jest": "^29.4.1",
39
- "typescript": "5.8.3",
40
- "@rushstack/heft-jest-plugin": "0.16.13",
41
- "@fgv/ts-utils-jest": "5.0.1-0"
42
- },
43
- "peerDependencies": {
44
- "typescript": "^5.7.3"
38
+ "ts-jest": "^29.4.5",
39
+ "typescript": "5.9.3",
40
+ "@rushstack/heft-jest-plugin": "1.1.3",
41
+ "@fgv/ts-utils-jest": "5.0.1-10"
45
42
  },
46
43
  "scripts": {
47
44
  "build": "heft build --clean",