W-22415490 feat: add generation of top level graphqlrc.yml file for generating react uiBundles#936
Conversation
| templates: getCustomTemplates(this.configAggregator), | ||
| }); | ||
|
|
||
| if (flags.template === 'reactbasic') { |
There was a problem hiding this comment.
in theory, this should be part of all UIBundles, in fact, maybe all of the sfdx projects. the issue is that in lwc ones, we don't pull the schema down.
Note: i would feel more comfortable if we add it for the ones we know and pull the schema.
There was a problem hiding this comment.
I had a question regarding the flags.template, according to Charles he said that he would expect it for reactbasic but not default because default is so minimal and unopinionated.
There was a problem hiding this comment.
Also, IIUC regarding the graphql schema file, I thought that the graphql.schema pulling happens outside of scope of running the sf cli commands sf template generate ui-bundle, it requires setup or manual calling of the script (or via graphiti CLI now)
- npm run graphql:schema
- node scripts/get-graphql-schema.mjs
| templateType: TemplateType.UIBundle, | ||
| opts: flagsAsOptions, | ||
| ux: new Ux({ jsonEnabled: this.jsonEnabled() }), | ||
| templates: getCustomTemplates(this.configAggregator), |
There was a problem hiding this comment.
Where's the origin of these "CustomTemplates"? what's the difference between adding it here (flags.template below), versus in the reactbasic "customTemplate"?
There was a problem hiding this comment.
@jodarove I'm not familiar with that construct, so here is claude's analysis of it:
getCustomTemplates and this.configAggregator
What it does
getCustomTemplates (src/utils/templateCommand.ts:26-33) is a tiny wrapper that reads a single Salesforce config property —
customOrgMetadataTemplates — from the supplied ConfigAggregator. It returns either the configured value (a string,
typically a path or git URL pointing to a custom templates source) or undefined if the key isn't set or reading throws.
export const getCustomTemplates = (configAggregator: ConfigAggregator): string | undefined => {
try {
return configAggregator.getPropertyValue(OrgConfigProperties.ORG_CUSTOM_METADATA_TEMPLATES) as string;
} catch (err) {
return undefined;
}
};
The returned string is forwarded into runGenerator as the templates option, which TemplateService.create(templateType,
opts, templates) uses to override the bundled templates with the user's custom set.
Why it's wrapped in try/catch
configAggregator.getPropertyValue can throw if the property metadata isn't registered or the config layer fails to resolve.
Swallowing the error to undefined lets TemplateService fall back to the default built-in templates instead of failing the
whole command.
How this.configAggregator gets there
this.configAggregator is not something this codebase constructs. It's a lazy-loaded property inherited from SfCommand
(which extends oclif's Command). When you read it inside a command class, sf-plugins-core resolves it on demand using
ConfigAggregator.create() from @salesforce/core, which:
1. Loads the global sfdx config (~/.sfdx/sfdx-config.json)
2. Loads the local project config (<project>/.sfdx/sfdx-config.json)
3. Layers env vars on top
Each command in this repo follows the same one-liner pattern at the call site — for example in
src/commands/template/generate/ui-bundle/index.ts:123:
templates: getCustomTemplates(this.configAggregator),
So this.configAggregator is the per-command aggregated view of all sf config sources, and getCustomTemplates queries one
specific key from it. If the user has set sf config set customOrgMetadataTemplates=<path-or-url>, that value flows through
here and overrides the bundled generators; otherwise the call returns undefined and the default templates are used.
| return { | ||
| ...result, | ||
| created: [...result.created, targetRelative], | ||
| rawOutput: `${result.rawOutput.replace(/\n$/, '')}\n create ${targetRelative}\n`, |
There was a problem hiding this comment.
is it create or created? we should match the others.
There was a problem hiding this comment.
This one should be create, as it is adding a new line to the output of generated files:
create force-app/main/default/uiBundles/MyUiBundle3/package.json
@W-22415490@