@fgv/ts-res 5.0.0-21 → 5.0.0-22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -29,70 +29,46 @@ npm install @fgv/ts-res
29
29
  ```typescript
30
30
  import * as TsRes from '@fgv/ts-res';
31
31
 
32
- // 1. Set up qualifier types
33
- const qualifierTypes = TsRes.QualifierTypes.QualifierTypeCollector.create({
34
- qualifierTypes: [
35
- TsRes.QualifierTypes.LanguageQualifierType.create().orThrow(),
36
- TsRes.QualifierTypes.TerritoryQualifierType.create().orThrow()
37
- ]
38
- }).orThrow();
39
-
40
- // 2. Define qualifiers with priorities
41
- const qualifiers = TsRes.Qualifiers.QualifierCollector.create({
42
- qualifierTypes,
43
- qualifiers: [
44
- { name: 'language', typeName: 'language', defaultPriority: 600 },
45
- { name: 'territory', typeName: 'territory', defaultPriority: 700 }
46
- ]
47
- }).orThrow();
32
+ // 1. Create a resource manager using predefined configuration
33
+ const manager = TsRes.Resources.ResourceManagerBuilder.createPredefined('default').orThrow();
48
34
 
49
- // 3. Set up resource types
50
- const resourceTypes = TsRes.ResourceTypes.ResourceTypeCollector.create({
51
- resourceTypes: [
52
- TsRes.ResourceTypes.JsonResourceType.create().orThrow()
35
+ // 2. Add resources with different language/territory conditions
36
+ manager.addResource({
37
+ id: 'greeting.message',
38
+ resourceTypeName: 'json',
39
+ candidates: [
40
+ {
41
+ json: { message: 'Hello' },
42
+ conditions: { language: 'en' }
43
+ },
44
+ {
45
+ json: { message: 'Bonjour' },
46
+ conditions: { language: 'fr' }
47
+ },
48
+ {
49
+ json: { message: 'Hello from Canada' },
50
+ conditions: {
51
+ language: 'en-CA',
52
+ currentTerritory: 'CA'
53
+ }
54
+ }
53
55
  ]
54
56
  }).orThrow();
55
57
 
56
- // 4. Create resource manager
57
- const manager = TsRes.Resources.ResourceManager.create({
58
- qualifiers,
59
- resourceTypes
60
- }).orThrow();
61
-
62
- // 5. Add resources
63
- const resources = [
64
- {
65
- id: 'greeting.message',
66
- json: { message: 'Hello' },
67
- conditions: { language: 'en' }
68
- },
69
- {
70
- id: 'greeting.message',
71
- json: { message: 'Bonjour' },
72
- conditions: { language: 'fr' }
73
- },
74
- {
75
- id: 'greeting.message',
76
- json: { message: 'Hello from Canada' },
77
- conditions: {
78
- language: 'en-CA',
79
- territory: 'CA'
80
- }
81
- }
82
- ];
83
-
84
- resources.forEach(resource => {
85
- manager.addLooseCandidate(resource).orThrow();
86
- });
87
-
88
- // 6. Build and resolve resources
58
+ // 3. Build the resource manager to prepare for resolution
89
59
  manager.build().orThrow();
90
60
 
91
- const greetingResource = manager.getBuiltResource('greeting.message').orThrow();
92
- const context = { language: 'en-CA', territory: 'CA' };
93
- const candidates = greetingResource.getCandidatesForContext(context);
61
+ // 4. Resolve resources for specific contexts
62
+ const resolver = TsRes.ResourceResolver.create(manager).orThrow();
63
+
64
+ // Get resolver for Canadian English context
65
+ const caResolver = resolver.withContext({
66
+ language: 'en-CA',
67
+ currentTerritory: 'CA'
68
+ }).orThrow();
94
69
 
95
- // Returns the most specific match: "Hello from Canada"
70
+ // Resolve the greeting message - returns: { message: "Hello from Canada" }
71
+ const greeting = caResolver.resolveComposedResourceValue('greeting.message').orThrow();
96
72
  ```
97
73
 
98
74
  ## Core Concepts
@@ -130,35 +106,34 @@ The library automatically selects the most appropriate resource based on:
130
106
  ### Resource Building with ResourceBuilder
131
107
 
132
108
  ```typescript
133
- const builder = TsRes.Resources.ResourceBuilder.create({
134
- qualifiers,
135
- resourceTypes
136
- }).orThrow();
109
+ // Using the resource manager's builder for individual resources
110
+ const manager = TsRes.Resources.ResourceManagerBuilder.createPredefined('default').orThrow();
137
111
 
138
- const resource = builder
139
- .withId('user.profile')
140
- .withResourceTypeName('json')
141
- .withCandidate({
142
- json: { title: 'Profile', button: 'Edit' },
143
- conditions: { language: 'en' }
144
- })
145
- .withCandidate({
146
- json: { title: 'Profil', button: 'Modifier' },
147
- conditions: { language: 'fr' }
148
- })
149
- .build()
150
- .orThrow();
151
-
152
- manager.addResource(resource).orThrow();
112
+ manager.addResource({
113
+ id: 'user.profile',
114
+ resourceTypeName: 'json',
115
+ candidates: [
116
+ {
117
+ json: { title: 'Profile', button: 'Edit' },
118
+ conditions: { language: 'en' }
119
+ },
120
+ {
121
+ json: { title: 'Profil', button: 'Modifier' },
122
+ conditions: { language: 'fr' }
123
+ }
124
+ ]
125
+ }).orThrow();
153
126
  ```
154
127
 
155
128
  ### File System Integration
156
129
 
157
130
  ```typescript
158
- // Import resources from file system
131
+ // Create a resource manager and import from file system
132
+ const manager = TsRes.Resources.ResourceManagerBuilder.createPredefined('default').orThrow();
133
+
159
134
  const importManager = TsRes.Import.ImportManager.create({
160
135
  filetree: fileTree,
161
- resources: resourceManager,
136
+ resources: manager,
162
137
  importers: TsRes.Import.ImportManager.getDefaultImporters(),
163
138
  initialContext: TsRes.Import.ImportContext.create().orThrow()
164
139
  }).orThrow();
@@ -182,16 +157,36 @@ Resources support different merge strategies:
182
157
  }
183
158
  ```
184
159
 
185
- ### Custom Qualifier Types
160
+ ### Custom System Configuration
186
161
 
187
162
  ```typescript
188
- const customType = TsRes.QualifierTypes.LiteralQualifierType.create({
189
- key: 'userType',
190
- values: ['admin', 'user', 'guest'],
191
- hierarchy: {
192
- 'admin': ['user', 'guest'],
193
- 'user': ['guest']
194
- }
163
+ // Create a system configuration with custom qualifiers and types
164
+ const customConfig = TsRes.Config.SystemConfiguration.create({
165
+ name: 'custom-config',
166
+ description: 'Custom configuration with user types',
167
+ qualifierTypes: [
168
+ TsRes.QualifierTypes.LanguageQualifierType.create().orThrow(),
169
+ TsRes.QualifierTypes.LiteralQualifierType.create({
170
+ key: 'userType',
171
+ values: ['admin', 'user', 'guest'],
172
+ hierarchy: {
173
+ 'admin': ['user', 'guest'],
174
+ 'user': ['guest']
175
+ }
176
+ }).orThrow()
177
+ ],
178
+ qualifiers: [
179
+ { name: 'language', typeName: 'language', defaultPriority: 600 },
180
+ { name: 'userType', typeName: 'userType', defaultPriority: 500 }
181
+ ],
182
+ resourceTypes: [
183
+ TsRes.ResourceTypes.JsonResourceType.create().orThrow()
184
+ ]
185
+ }).orThrow();
186
+
187
+ const manager = TsRes.Resources.ResourceManagerBuilder.create({
188
+ qualifiers: customConfig.qualifiers,
189
+ resourceTypes: customConfig.resourceTypes
195
190
  }).orThrow();
196
191
  ```
197
192
 
@@ -199,22 +194,26 @@ const customType = TsRes.QualifierTypes.LiteralQualifierType.create({
199
194
 
200
195
  ### Core Classes
201
196
 
202
- - **ResourceManager**: Central orchestrator for resource operations
197
+ - **ResourceManagerBuilder**: Central builder for resource management systems
198
+ - **ResourceResolver**: Runtime resolver for getting resources in specific contexts
203
199
  - **Resource**: Individual resource with candidates for different contexts
204
200
  - **ResourceCandidate**: Specific resource variant with conditions
205
- - **ResourceBuilder**: Builder pattern for constructing resources
206
- - **QualifierCollector**: Manages qualifier definitions
201
+ - **SystemConfiguration**: Configuration defining qualifiers, types, and defaults
202
+ - **Condition**: Individual condition with qualifier, operator, and value
207
203
  - **ConditionSet**: Collection of conditions for resource matching
208
204
 
209
205
  ### Namespaces
210
206
 
211
- - **Resources**: Core resource management classes
207
+ - **Resources**: Core resource management classes (`ResourceManagerBuilder`, etc.)
208
+ - **Config**: System configuration classes (`SystemConfiguration`, predefined configs)
212
209
  - **Qualifiers**: Qualifier definition and management
213
210
  - **Conditions**: Condition and condition set management
214
211
  - **QualifierTypes**: Built-in and custom qualifier type definitions
215
212
  - **Context**: Context definition for resource resolution
216
213
  - **Import**: File system and external resource import utilities
217
214
  - **ResourceJson**: JSON serialization and deserialization
215
+ - **Bundle**: Resource bundling and deployment utilities
216
+ - **Runtime**: Runtime resolution classes (`ResourceResolver`, etc.)
218
217
 
219
218
  ## Context Filtering and Qualifier Reduction
220
219
 
@@ -299,6 +298,10 @@ const completeBundle = resourceManager.getResourceCollectionDecl().orThrow();
299
298
  Filter for a specific environment (e.g., production):
300
299
 
301
300
  ```typescript
301
+ const resourceManager = TsRes.Resources.ResourceManagerBuilder.createPredefined('default').orThrow();
302
+ // ... add feature flag resources ...
303
+ resourceManager.build().orThrow();
304
+
302
305
  const productionContext = resourceManager.validateContext({
303
306
  environment: 'production'
304
307
  }).orThrow();
@@ -475,33 +478,58 @@ const result = resource.toLooseResourceDecl({
475
478
  ### Web Application Localization
476
479
 
477
480
  ```typescript
478
- // Set up for multi-language, multi-region application
479
- const qualifiers = [
480
- { name: 'language', typeName: 'language', defaultPriority: 600 },
481
- { name: 'homeTerritory', typeName: 'territory', defaultPriority: 700 },
482
- { name: 'currentTerritory', typeName: 'territory', defaultPriority: 800 }
483
- ];
481
+ // Use predefined configuration or create custom one with territories
482
+ const manager = TsRes.Resources.ResourceManagerBuilder.createPredefined('territoryPriority').orThrow();
484
483
 
485
- // Resources with fallback chains
486
- const resources = [
487
- // Default English
488
- { id: 'app.title', json: { title: 'My App' }, conditions: { language: 'en' } },
489
- // Canadian English variant
490
- { id: 'app.title', json: { title: 'My App, eh!' }, conditions: { language: 'en-CA' } },
491
- // French
492
- { id: 'app.title', json: { title: 'Mon App' }, conditions: { language: 'fr' } }
493
- ];
484
+ manager.addResource({
485
+ id: 'app.title',
486
+ resourceTypeName: 'json',
487
+ candidates: [
488
+ // Default English
489
+ { json: { title: 'My App' }, conditions: { language: 'en' } },
490
+ // Canadian English variant
491
+ { json: { title: 'My App, eh!' }, conditions: { language: 'en-CA' } },
492
+ // French
493
+ { json: { title: 'Mon App' }, conditions: { language: 'fr' } }
494
+ ]
495
+ }).orThrow();
496
+
497
+ manager.build().orThrow();
498
+
499
+ // Create resolver for Canadian user
500
+ const resolver = TsRes.ResourceResolver.create(manager).orThrow();
501
+ const canadianResolver = resolver.withContext({
502
+ language: 'en-CA',
503
+ currentTerritory: 'CA'
504
+ }).orThrow();
505
+
506
+ const title = canadianResolver.resolveComposedResourceValue('app.title').orThrow();
507
+ // Returns: { title: 'My App, eh!' }
494
508
  ```
495
509
 
496
510
  ### Configuration Management
497
511
 
498
512
  ```typescript
499
- // Environment-specific configurations
500
- const configs = [
501
- { id: 'api.config', json: { url: 'localhost:3000' }, conditions: { env: 'development' } },
502
- { id: 'api.config', json: { url: 'api.staging.com' }, conditions: { env: 'staging' } },
503
- { id: 'api.config', json: { url: 'api.production.com' }, conditions: { env: 'production' } }
504
- ];
513
+ // Create manager with custom environment qualifier
514
+ const manager = TsRes.Resources.ResourceManagerBuilder.createPredefined('default').orThrow();
515
+
516
+ manager.addResource({
517
+ id: 'api.config',
518
+ resourceTypeName: 'json',
519
+ candidates: [
520
+ { json: { url: 'localhost:3000' }, conditions: { environment: 'development' } },
521
+ { json: { url: 'api.staging.com' }, conditions: { environment: 'staging' } },
522
+ { json: { url: 'api.production.com' }, conditions: { environment: 'production' } }
523
+ ]
524
+ }).orThrow();
525
+
526
+ manager.build().orThrow();
527
+
528
+ // Resolve configuration for production
529
+ const resolver = TsRes.ResourceResolver.create(manager).orThrow();
530
+ const prodResolver = resolver.withContext({ environment: 'production' }).orThrow();
531
+ const config = prodResolver.resolveComposedResourceValue('api.config').orThrow();
532
+ // Returns: { url: 'api.production.com' }
505
533
  ```
506
534
 
507
535
  ## Dependencies
@@ -515,24 +543,32 @@ const configs = [
515
543
 
516
544
  ## Development
517
545
 
546
+ This library is part of a Rush monorepo. Development commands:
547
+
518
548
  ```bash
519
- # Install dependencies
520
- npm install
549
+ # Install dependencies (from repository root)
550
+ rush install
521
551
 
522
- # Build the project
523
- npm run build
552
+ # Build the project
553
+ rushx build
524
554
 
525
555
  # Run tests
526
- npm run test
556
+ rushx test
527
557
 
528
558
  # Run tests with coverage
529
- npm run coverage
559
+ rushx coverage
530
560
 
531
561
  # Lint code
532
- npm run lint
562
+ rushx lint
563
+
564
+ # Fix linting issues
565
+ rushx fixlint
566
+
567
+ # Generate API documentation
568
+ rushx build-docs
533
569
 
534
- # Generate documentation
535
- npm run build-docs
570
+ # Build project and docs together
571
+ rushx build-all
536
572
  ```
537
573
 
538
574
  ## License
package/dist/ts-res.d.ts CHANGED
@@ -707,7 +707,8 @@ declare namespace Common {
707
707
  ResourceTypeIndex,
708
708
  ResourceValueMergeMethod,
709
709
  allResourceValueMergeMethods,
710
- CandidateCompleteness
710
+ CandidateCompleteness,
711
+ IResourceResolver
711
712
  }
712
713
  }
713
714
 
@@ -3828,6 +3829,11 @@ declare interface IJsonResourceTypeCreateParams {
3828
3829
  * instance.
3829
3830
  */
3830
3831
  index?: number;
3832
+ /**
3833
+ * Optional template for new instances of {@link ResourceTypes.JsonResourceType | JsonResourceType}
3834
+ * resources.
3835
+ */
3836
+ template?: JsonObject;
3831
3837
  }
3832
3838
 
3833
3839
  /**
@@ -4960,6 +4966,31 @@ declare interface IResourceManagerCloneOptions extends IResourceDeclarationOptio
4960
4966
  readonly resourceTypes?: ReadOnlyResourceTypeCollector;
4961
4967
  }
4962
4968
 
4969
+ /**
4970
+ * Minimal resource resolver
4971
+ * @public
4972
+ */
4973
+ export declare interface IResourceResolver {
4974
+ /**
4975
+ * Resolves a resource to a composed value by merging matching candidates according to their merge methods.
4976
+ * Starting from the highest priority candidates, finds the first "full" candidate and merges all higher
4977
+ * priority "partial" candidates into it in ascending order of priority.
4978
+ * @param resource - The string id of the resource to resolve.
4979
+ * @returns `Success` with the composed JsonValue if successful,
4980
+ * or `Failure` with an error message if no candidates match or resolution fails.
4981
+ * @public
4982
+ */
4983
+ resolveComposedResourceValue(resource: string): Result<JsonValue>;
4984
+ /**
4985
+ * Creates a new {@link IResourceResolver | resource resolver} with the given context.
4986
+ * @param context - The context to use for the new resource resolver.
4987
+ * @returns `Success` with the new resource resolver if successful,
4988
+ * or `Failure` with an error message if the context is invalid.
4989
+ * @public
4990
+ */
4991
+ withContext(context: Record<string, string>): Result<IResourceResolver>;
4992
+ }
4993
+
4963
4994
  /**
4964
4995
  * A listener for {@link Runtime.ResourceResolver | ResourceResolver} cache activity.
4965
4996
  * @public
@@ -5161,11 +5192,14 @@ declare interface IResourceType<T = unknown> extends ICollectible<ResourceTypeNa
5161
5192
  /**
5162
5193
  * Creates a template for a new resource of this type.
5163
5194
  * The template provides a default structure for creating new resource instances.
5164
- * @param resourceId - The id for the new resource
5165
- * @returns A loose resource declaration with default values for this resource type
5195
+ * @param resourceId - The id for the new resource.
5196
+ * @param init - An optional initial value for the resource.
5197
+ * @param resolver - An optional resource resolver that can be used to create the template.
5198
+ * @param conditions - An optional set of conditions that must be met for the resource to be selected.
5199
+ * @returns A loose resource declaration with default values for this resource type.
5166
5200
  * @public
5167
5201
  */
5168
- createTemplate(resourceId: ResourceId): ResourceJson.Json.ILooseResourceDecl;
5202
+ createTemplate(resourceId: ResourceId, init?: JsonValue, conditions?: ResourceJson.Json.ConditionSetDecl, resolver?: IResourceResolver): Result<ResourceJson.Json.ILooseResourceDecl>;
5169
5203
  }
5170
5204
 
5171
5205
  /**
@@ -5175,6 +5209,7 @@ declare interface IResourceType<T = unknown> extends ICollectible<ResourceTypeNa
5175
5209
  declare interface IResourceTypeConfig {
5176
5210
  name: string;
5177
5211
  typeName: string;
5212
+ template?: JsonObject;
5178
5213
  }
5179
5214
 
5180
5215
  /**
@@ -5899,7 +5934,7 @@ declare class JsonResourceType extends ResourceType<JsonObject> {
5899
5934
  * @param key - The key for the new {@link ResourceTypes.JsonResourceType | JsonResourceType} instance.
5900
5935
  * @param index - Optional index for the new {@link ResourceTypes.JsonResourceType | JsonResourceType} instance.
5901
5936
  */
5902
- protected constructor(key: ResourceTypeName, index?: number);
5937
+ protected constructor(key: ResourceTypeName, index?: number, template?: JsonObject);
5903
5938
  /**
5904
5939
  * Factory method to create a new {@link ResourceTypes.JsonResourceType | JsonResourceType} instance.
5905
5940
  * @param params - {@link ResourceTypes.IJsonResourceTypeCreateParams | Parameters} to create the new instance.
@@ -5923,11 +5958,6 @@ declare class JsonResourceType extends ResourceType<JsonObject> {
5923
5958
  * {@inheritdoc ResourceTypes.ResourceType.(validate:3)}
5924
5959
  */
5925
5960
  validate(json: JsonObject, completeness: 'partial'): Result<JsonObject>;
5926
- /**
5927
- * Gets the default template value for a JSON resource type.
5928
- * @returns An empty object as the default JSON value
5929
- */
5930
- protected getDefaultTemplateValue(): JsonObject;
5931
5961
  }
5932
5962
 
5933
5963
  /**
@@ -8163,7 +8193,7 @@ declare const resourceName: Converter<ResourceName, unknown>;
8163
8193
  * and caching results for optimal performance.
8164
8194
  * @public
8165
8195
  */
8166
- export declare class ResourceResolver {
8196
+ export declare class ResourceResolver implements IResourceResolver {
8167
8197
  /**
8168
8198
  * The resource manager that defines available resources and provides condition access.
8169
8199
  */
@@ -8180,6 +8210,10 @@ export declare class ResourceResolver {
8180
8210
  * The configuration options for this resource resolver.
8181
8211
  */
8182
8212
  readonly options: IResourceResolverOptions;
8213
+ /**
8214
+ * The readonly qualifier collector that provides qualifier implementations.
8215
+ */
8216
+ get qualifiers(): IReadOnlyQualifierCollector;
8183
8217
  /**
8184
8218
  * The cache array for resolved conditions, indexed by condition index for O(1) lookup.
8185
8219
  * Each entry stores the resolved {@link Runtime.IConditionMatchResult | condition match result} for
@@ -8264,6 +8298,15 @@ export declare class ResourceResolver {
8264
8298
  * @public
8265
8299
  */
8266
8300
  resolveResource(resource: IResource): Result<IResourceCandidate>;
8301
+ /**
8302
+ * Resolves a resource by finding the best matching candidate.
8303
+ * Uses the resource's associated decision to determine the best match based on the current context.
8304
+ * @param resource - The string id of the resource to resolve.
8305
+ * @returns `Success` with the best matching candidate if successful,
8306
+ * or `Failure` with an error message if no candidates match or resolution fails.
8307
+ * @public
8308
+ */
8309
+ resolveResource(resource: string): Result<IResourceCandidate>;
8267
8310
  /**
8268
8311
  * Resolves all matching resource candidates in priority order.
8269
8312
  * Uses the resource's associated decision to determine all matching candidates based on the current context.
@@ -8273,6 +8316,15 @@ export declare class ResourceResolver {
8273
8316
  * @public
8274
8317
  */
8275
8318
  resolveAllResourceCandidates(resource: IResource): Result<ReadonlyArray<IResourceCandidate>>;
8319
+ /**
8320
+ * Resolves all matching resource candidates in priority order.
8321
+ * Uses the resource's associated decision to determine all matching candidates based on the current context.
8322
+ * @param resource - The string id of the resource to resolve.
8323
+ * @returns `Success` with an array of all matching candidates in priority order if successful,
8324
+ * or `Failure` with an error message if no candidates match or resolution fails.
8325
+ * @public
8326
+ */
8327
+ resolveAllResourceCandidates(resource: string): Result<ReadonlyArray<IResourceCandidate>>;
8276
8328
  /**
8277
8329
  * Resolves a resource to a composed value by merging matching candidates according to their merge methods.
8278
8330
  * Starting from the highest priority candidates, finds the first "full" candidate and merges all higher
@@ -8283,6 +8335,20 @@ export declare class ResourceResolver {
8283
8335
  * @public
8284
8336
  */
8285
8337
  resolveComposedResourceValue(resource: IResource): Result<JsonValue>;
8338
+ /**
8339
+ * Resolves a resource to a composed value by merging matching candidates according to their merge methods.
8340
+ * Starting from the highest priority candidates, finds the first "full" candidate and merges all higher
8341
+ * priority "partial" candidates into it in ascending order of priority.
8342
+ * @param resource - The string id of the resource to resolve.
8343
+ * @returns `Success` with the composed JsonValue if successful,
8344
+ * or `Failure` with an error message if no candidates match or resolution fails.
8345
+ * @public
8346
+ */
8347
+ resolveComposedResourceValue(resource: string): Result<JsonValue>;
8348
+ /**
8349
+ * {@inheritDoc IResourceResolver.withContext}
8350
+ */
8351
+ withContext(context: Record<string, string>): Result<ResourceResolver>;
8286
8352
  /**
8287
8353
  * Clears all caches (condition, condition set, and decision), forcing all cached items
8288
8354
  * to be re-evaluated on next access. This should be called when the context changes and cached
@@ -8533,6 +8599,7 @@ declare const resourceTreeRootDecl: Converter<Normalized.IResourceTreeRootDecl>;
8533
8599
  */
8534
8600
  export declare abstract class ResourceType<T = unknown> implements IResourceType<T> {
8535
8601
  private _collectible;
8602
+ private _template;
8536
8603
  /**
8537
8604
  * {@inheritdoc ResourceTypes.IResourceType.key}
8538
8605
  */
@@ -8541,7 +8608,7 @@ export declare abstract class ResourceType<T = unknown> implements IResourceType
8541
8608
  * {@inheritdoc ResourceTypes.IResourceType.index}
8542
8609
  */
8543
8610
  get index(): ResourceTypeIndex | undefined;
8544
- protected constructor(key: ResourceTypeName, index?: number);
8611
+ protected constructor(key: ResourceTypeName, index?: number, template?: JsonObject);
8545
8612
  /**
8546
8613
  * Validates properties of a {@link ResourceJson.Json.ILooseResourceCandidateDecl | resource candidate declaration} for
8547
8614
  * a resource instance value.
@@ -8596,16 +8663,20 @@ export declare abstract class ResourceType<T = unknown> implements IResourceType
8596
8663
  * Default implementation provides a basic template.
8597
8664
  * Subclasses can override to provide type-specific templates.
8598
8665
  * @param resourceId - The id for the new resource
8666
+ * @param init - An optional initial value for the resource.
8667
+ * @param conditions - An optional set of conditions that must be met for the resource to be selected.
8668
+ * @param resolver - An optional resource resolver that can be used to create the template.
8599
8669
  * @returns A loose resource declaration with default values for this resource type
8600
8670
  * @public
8601
8671
  */
8602
- createTemplate(resourceId: ResourceId): ResourceJson.Json.ILooseResourceDecl;
8672
+ createTemplate(resourceId: ResourceId, init?: JsonValue, conditions?: ResourceJson.Json.ConditionSetDecl, resolver?: IResourceResolver): Result<ResourceJson.Json.ILooseResourceDecl>;
8603
8673
  /**
8604
8674
  * Gets the default template value for this resource type.
8605
8675
  * Subclasses should override this to provide type-specific default values.
8606
8676
  * @returns The default JSON value for a new resource of this type
8677
+ * @public
8607
8678
  */
8608
- protected getDefaultTemplateValue(): JsonObject;
8679
+ getDefaultTemplateCandidate(json?: JsonValue, conditions?: ResourceJson.Json.ConditionSetDecl, __resolver?: IResourceResolver): Result<ResourceJson.Json.IChildResourceCandidateDecl>;
8609
8680
  }
8610
8681
 
8611
8682
  /**
@@ -1,4 +1,5 @@
1
- import { Brand } from '@fgv/ts-utils';
1
+ import { JsonValue } from '@fgv/ts-json-base';
2
+ import { Brand, Result } from '@fgv/ts-utils';
2
3
  /**
3
4
  * Branded string representing a validated resource id. A resource ID
4
5
  * is a dot-separated sequence of resource names.
@@ -46,4 +47,28 @@ export declare const allResourceValueMergeMethods: ResourceValueMergeMethod[];
46
47
  * @public
47
48
  */
48
49
  export type CandidateCompleteness = 'full' | 'partial';
50
+ /**
51
+ * Minimal resource resolver
52
+ * @public
53
+ */
54
+ export interface IResourceResolver {
55
+ /**
56
+ * Resolves a resource to a composed value by merging matching candidates according to their merge methods.
57
+ * Starting from the highest priority candidates, finds the first "full" candidate and merges all higher
58
+ * priority "partial" candidates into it in ascending order of priority.
59
+ * @param resource - The string id of the resource to resolve.
60
+ * @returns `Success` with the composed JsonValue if successful,
61
+ * or `Failure` with an error message if no candidates match or resolution fails.
62
+ * @public
63
+ */
64
+ resolveComposedResourceValue(resource: string): Result<JsonValue>;
65
+ /**
66
+ * Creates a new {@link IResourceResolver | resource resolver} with the given context.
67
+ * @param context - The context to use for the new resource resolver.
68
+ * @returns `Success` with the new resource resolver if successful,
69
+ * or `Failure` with an error message if the context is invalid.
70
+ * @public
71
+ */
72
+ withContext(context: Record<string, string>): Result<IResourceResolver>;
73
+ }
49
74
  //# sourceMappingURL=resources.d.ts.map
@@ -24,6 +24,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.resourceTypeConfig = void 0;
25
25
  /* eslint-disable @rushstack/typedef-var */
26
26
  const ts_utils_1 = require("@fgv/ts-utils");
27
+ const ts_json_base_1 = require("@fgv/ts-json-base");
27
28
  /**
28
29
  * A `Converter` for {@link ResourceTypes.Config.IResourceTypeConfig | ResourceTypeConfig} objects.
29
30
  * @returns A `Converter` for {@link ResourceTypes.Config.IResourceTypeConfig | ResourceTypeConfig} objects.
@@ -31,6 +32,7 @@ const ts_utils_1 = require("@fgv/ts-utils");
31
32
  */
32
33
  exports.resourceTypeConfig = ts_utils_1.Converters.strictObject({
33
34
  name: ts_utils_1.Converters.string,
34
- typeName: ts_utils_1.Converters.string
35
+ typeName: ts_utils_1.Converters.string,
36
+ template: ts_json_base_1.Converters.jsonObject.optional()
35
37
  });
36
38
  //# sourceMappingURL=convert.js.map
@@ -1,3 +1,4 @@
1
+ import { JsonObject } from '@fgv/ts-json-base';
1
2
  /**
2
3
  * Configuration for a {@link ResourceTypes.ResourceType | resource type}.
3
4
  * @public
@@ -5,5 +6,6 @@
5
6
  export interface IResourceTypeConfig {
6
7
  name: string;
7
8
  typeName: string;
9
+ template?: JsonObject;
8
10
  }
9
11
  //# sourceMappingURL=json.d.ts.map
@@ -17,6 +17,11 @@ export interface IJsonResourceTypeCreateParams {
17
17
  * instance.
18
18
  */
19
19
  index?: number;
20
+ /**
21
+ * Optional template for new instances of {@link ResourceTypes.JsonResourceType | JsonResourceType}
22
+ * resources.
23
+ */
24
+ template?: JsonObject;
20
25
  }
21
26
  /**
22
27
  * Implementation of a {@link ResourceTypes.ResourceType | ResourceType} for JSON values.
@@ -29,7 +34,7 @@ export declare class JsonResourceType extends ResourceType<JsonObject> {
29
34
  * @param key - The key for the new {@link ResourceTypes.JsonResourceType | JsonResourceType} instance.
30
35
  * @param index - Optional index for the new {@link ResourceTypes.JsonResourceType | JsonResourceType} instance.
31
36
  */
32
- protected constructor(key: ResourceTypeName, index?: number);
37
+ protected constructor(key: ResourceTypeName, index?: number, template?: JsonObject);
33
38
  /**
34
39
  * Factory method to create a new {@link ResourceTypes.JsonResourceType | JsonResourceType} instance.
35
40
  * @param params - {@link ResourceTypes.IJsonResourceTypeCreateParams | Parameters} to create the new instance.
@@ -53,10 +58,5 @@ export declare class JsonResourceType extends ResourceType<JsonObject> {
53
58
  * {@inheritdoc ResourceTypes.ResourceType.(validate:3)}
54
59
  */
55
60
  validate(json: JsonObject, completeness: 'partial'): Result<JsonObject>;
56
- /**
57
- * Gets the default template value for a JSON resource type.
58
- * @returns An empty object as the default JSON value
59
- */
60
- protected getDefaultTemplateValue(): JsonObject;
61
61
  }
62
62
  //# sourceMappingURL=jsonResourceType.d.ts.map