From c4b3a843f18f1771b96ee9b43ad3424027966232 Mon Sep 17 00:00:00 2001 From: Ricardo Viera Date: Fri, 5 Dec 2025 09:38:36 -0700 Subject: [PATCH 1/3] feat: add rules eval command and template list filtering - Move orchestrator template eval to orchestrator rules eval - Update flag names to match Analytics template files: --template-info, --variables, --rules - Make all template files required for complete validation - Add --all flag to template list to show/hide standard Salesforce templates - Filter out sfdc_internal__ templates by default to reduce noise - Update command snapshots and tests for new structure --- command-snapshot.json | 16 ++-- messages/appframework.list.template.md | 22 ++++++ messages/orchestrator.rules.eval.md | 55 ++++++++++++++ messages/orchestrator.template.eval.md | 58 -------------- package.json | 6 ++ .../orchestrator/{template => rules}/eval.ts | 76 ++++++++----------- src/commands/orchestrator/template/list.ts | 15 +++- .../rules/eval.nut.ts} | 9 +-- .../rules/eval.test.ts} | 6 +- 9 files changed, 144 insertions(+), 119 deletions(-) create mode 100644 messages/orchestrator.rules.eval.md delete mode 100644 messages/orchestrator.template.eval.md rename src/commands/orchestrator/{template => rules}/eval.ts (71%) rename test/commands/{template/preview.nut.ts => orchestrator/rules/eval.nut.ts} (82%) rename test/commands/{template/preview.test.ts => orchestrator/rules/eval.test.ts} (84%) diff --git a/command-snapshot.json b/command-snapshot.json index ccffbea..ba91427 100644 --- a/command-snapshot.json +++ b/command-snapshot.json @@ -71,6 +71,14 @@ ], "plugin": "@salesforce/plugin-orchestrator" }, + { + "alias": [], + "command": "orchestrator:rules:eval", + "flagAliases": [], + "flagChars": ["o", "r", "t", "v"], + "flags": ["api-version", "flags-dir", "json", "rules", "target-org", "template-info", "variables"], + "plugin": "@salesforce/plugin-orchestrator" + }, { "alias": [], "command": "orchestrator:template:create", @@ -95,14 +103,6 @@ "flags": ["api-version", "flags-dir", "json", "target-org", "template-id", "template-name"], "plugin": "@salesforce/plugin-orchestrator" }, - { - "alias": [], - "command": "orchestrator:template:eval", - "flagAliases": [], - "flagChars": ["d", "o", "r", "v"], - "flags": ["api-version", "definition-file", "document-file", "flags-dir", "json", "target-org", "values-file"], - "plugin": "@salesforce/plugin-orchestrator" - }, { "alias": [], "command": "orchestrator:template:list", diff --git a/messages/appframework.list.template.md b/messages/appframework.list.template.md index be7f569..eb49c36 100644 --- a/messages/appframework.list.template.md +++ b/messages/appframework.list.template.md @@ -6,6 +6,8 @@ List all available templates in the target org. Templates are reusable configurations that define the structure and settings for creating orchestrated apps. Use this command to discover available templates in your org before creating new apps. +By default, this command only shows custom templates created in your org. Standard Salesforce-provided templates are filtered out to reduce noise. Use the --all flag to include all templates including the standard ones. + Templates are displayed in a table format showing their name, label, ID, type, and other metadata. This information helps you choose the right template for your orchestrated app development. You must have Data Cloud and Tableau Next enabled in your org and the AppFrameworkViewApp user permission to view templates. This command works with production orgs, sandboxes, and scratch orgs. @@ -28,6 +30,14 @@ You must have Data Cloud and Tableau Next enabled in your org and the AppFramewo <%= config.bin %> <%= command.id %> --target-org mySandbox --api-version 60.0 +- List all templates including standard Salesforce templates: + + <%= config.bin %> <%= command.id %> --all + +- List all templates in a specific org: + + <%= config.bin %> <%= command.id %> --target-org myOrg --all + # flags.target-org.summary Login username or alias for the target org. @@ -44,6 +54,14 @@ Override the API version used for API requests. Override the API version used for orchestrator API requests. Use this flag to specify a particular API version when the default version doesn't work with your org's configuration. +# flags.all.summary + +Show all templates including standard Salesforce templates. + +# flags.all.description + +By default, this command only shows custom templates created in your org. Use this flag to include the standard Salesforce-provided templates (those starting with 'sfdc_internal\_\_') in the results. + # templatesFound Found %s templates: @@ -52,6 +70,10 @@ Found %s templates: No templates found. +# noCustomTemplatesFound + +No custom templates found. Use --all to include standard Salesforce templates. + # fetchingTemplates Fetching templates... diff --git a/messages/orchestrator.rules.eval.md b/messages/orchestrator.rules.eval.md new file mode 100644 index 0000000..197d2ee --- /dev/null +++ b/messages/orchestrator.rules.eval.md @@ -0,0 +1,55 @@ +# summary + +Test JSON transformation rules using the jsonxform/transformation endpoint. + +# description + +Preview how transformation rules will modify JSON documents before deploying templates. This command uses a sample transformation to test the jsonxform/transformation endpoint with built-in User and Org context variables. + +# flags.target-org.summary + +Username or alias for the target org; overrides default target org. + +# flags.target-org.description + +The username or alias of the target org where the jsonxform/transformation endpoint will be called. This org provides the User and Org context variables used in the transformation. + +# flags.api-version.summary + +Override the api version used for api requests made by this command. + +# flags.api-version.description + +API version to use for the transformation request. Defaults to the org's configured API version. + +# flags.template-info.summary + +Path to Analytics template-info.json file. + +# flags.template-info.description + +Path to the template-info.json file containing the base JSON document structure that will be transformed. + +# flags.variables.summary + +Path to Analytics variables.json file. + +# flags.variables.description + +Path to the variables.json file containing variable definitions used in transformations. + +# flags.rules.summary + +Path to Analytics rules.json file. + +# flags.rules.description + +Path to the rules.json file containing transformation rules and macro definitions. + +# examples + +- Test JSON transformation with Analytics template files: + <%= config.bin %> <%= command.id %> --template-info ./template-info.json --variables ./variables.json --rules ./rules.json --target-org myorg + +- Test with specific API version: + <%= config.bin %> <%= command.id %> --template-info ./template-info.json --variables ./variables.json --rules ./rules.json --target-org myorg --api-version 60.0 diff --git a/messages/orchestrator.template.eval.md b/messages/orchestrator.template.eval.md deleted file mode 100644 index bc185f3..0000000 --- a/messages/orchestrator.template.eval.md +++ /dev/null @@ -1,58 +0,0 @@ -# summary - -Test JSON transformation rules using the jsonxform/transformation endpoint. - -# description - -Preview how transformation rules will modify JSON documents before deploying templates. This command uses a sample transformation to test the jsonxform/transformation endpoint with built-in User and Org context variables. - -# flags.target-org.summary - -Username or alias for the target org; overrides default target org. - -# flags.target-org.description - -The username or alias of the target org where the jsonxform/transformation endpoint will be called. This org provides the User and Org context variables used in the transformation. - -# flags.api-version.summary - -Override the api version used for api requests made by this command. - -# flags.api-version.description - -API version to use for the transformation request. Defaults to the org's configured API version. - -# flags.document-file.summary - -Path to JSON document file to transform. - -# flags.document-file.description - -Path to the JSON document file that will be transformed by the rules. - -# flags.values-file.summary - -Path to JSON values file for variables. - -# flags.values-file.description - -Path to JSON file containing variables used in transformations. - -# flags.definition-file.summary - -Path to JSON rules definition file. - -# flags.definition-file.description - -Path to JSON file containing transformation rules and definitions. - -# examples - -- Test JSON transformation with document file only: - <%= config.bin %> <%= command.id %> --document-file ./document.json --target-org myorg - -- Test with document, values, and rules files: - <%= config.bin %> <%= command.id %> --document-file ./document.json --values-file ./values.json --definition-file ./rules.json --target-org myorg - -- Test with specific API version: - <%= config.bin %> <%= command.id %> --document-file ./document.json --target-org myorg --api-version 60.0 diff --git a/package.json b/package.json index aa82ef8..3ce1ed7 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,9 @@ "subtopics": { "app": { "external": true + }, + "rules": { + "external": true } } }, @@ -71,6 +74,9 @@ "orchestrator:template": { "description": "Work with templates" }, + "orchestrator:rules": { + "description": "Work with transformation rules" + }, "template": { "description": "description for template" } diff --git a/src/commands/orchestrator/template/eval.ts b/src/commands/orchestrator/rules/eval.ts similarity index 71% rename from src/commands/orchestrator/template/eval.ts rename to src/commands/orchestrator/rules/eval.ts index 9bb32c4..b5a94a1 100644 --- a/src/commands/orchestrator/template/eval.ts +++ b/src/commands/orchestrator/rules/eval.ts @@ -19,7 +19,7 @@ import { SfCommand, Flags } from '@salesforce/sf-plugins-core'; import { Messages, Connection } from '@salesforce/core'; Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); -const messages = Messages.loadMessages('@salesforce/plugin-orchestrator', 'orchestrator.template.eval'); +const messages = Messages.loadMessages('@salesforce/plugin-orchestrator', 'orchestrator.rules.eval'); type TransformationPayload = { document: { @@ -85,23 +85,23 @@ export default class TemplateEval extends SfCommand { summary: messages.getMessage('flags.api-version.summary'), description: messages.getMessage('flags.api-version.description'), }), - 'document-file': Flags.file({ - char: 'd', - summary: messages.getMessage('flags.document-file.summary'), - description: messages.getMessage('flags.document-file.description'), + 'template-info': Flags.file({ + char: 't', + summary: messages.getMessage('flags.template-info.summary'), + description: messages.getMessage('flags.template-info.description'), required: true, }), - 'values-file': Flags.file({ + variables: Flags.file({ char: 'v', - summary: messages.getMessage('flags.values-file.summary'), - description: messages.getMessage('flags.values-file.description'), - dependsOn: ['document-file'], + summary: messages.getMessage('flags.variables.summary'), + description: messages.getMessage('flags.variables.description'), + required: true, }), - 'definition-file': Flags.file({ + rules: Flags.file({ char: 'r', - summary: messages.getMessage('flags.definition-file.summary'), - description: messages.getMessage('flags.definition-file.description'), - dependsOn: ['document-file'], + summary: messages.getMessage('flags.rules.summary'), + description: messages.getMessage('flags.rules.description'), + required: true, }), }; @@ -159,51 +159,41 @@ export default class TemplateEval extends SfCommand { } } - private async getTemplatePayload(flags: { - 'document-file': string; - 'values-file'?: string; - 'definition-file'?: string; - }): Promise<{ + private async getTemplatePayload(flags: { 'template-info': string; variables: string; rules: string }): Promise<{ template: TemplateInfo; payload: TransformationPayload; }> { - return this.getDirectFilePayload(flags['document-file'], flags['values-file'], flags['definition-file']); + return this.getDirectFilePayload(flags['template-info'], flags['variables'], flags['rules']); } private async getDirectFilePayload( - documentFile: string, - valuesFile?: string, - definitionFile?: string + templateInfoFile: string, + variablesFile: string, + rulesFile: string ): Promise<{ template: TemplateInfo; payload: TransformationPayload; }> { - this.log(`Loading document: ${documentFile}`); - - // Read and parse the document file - const documentContent = await fs.readFile(documentFile, 'utf8'); - const document = JSON.parse(documentContent) as unknown; - - // Read values file if provided, otherwise use empty object - let values = { Variables: { hello: 'world' } }; - if (valuesFile) { - this.log(`Loading values: ${valuesFile}`); - const valuesContent = await fs.readFile(valuesFile, 'utf8'); - values = JSON.parse(valuesContent) as typeof values; - } + this.log(`Loading template info: ${templateInfoFile}`); - // Read definition file if provided, otherwise use empty rules - let definition = { rules: [] }; - if (definitionFile) { - this.log(`Loading definition: ${definitionFile}`); - const definitionContent = await fs.readFile(definitionFile, 'utf8'); - definition = JSON.parse(definitionContent) as typeof definition; - } + // Read and parse the template-info file + const templateInfoContent = await fs.readFile(templateInfoFile, 'utf8'); + const document = JSON.parse(templateInfoContent) as unknown; + + // Read variables file + this.log(`Loading variables: ${variablesFile}`); + const variablesContent = await fs.readFile(variablesFile, 'utf8'); + const values = JSON.parse(variablesContent) as { Variables: Record }; + + // Read rules file + this.log(`Loading rules: ${rulesFile}`); + const rulesContent = await fs.readFile(rulesFile, 'utf8'); + const definition = JSON.parse(rulesContent) as { rules: unknown[] }; return { template: { name: 'Direct Files', - path: documentFile, + path: templateInfoFile, source: 'local' as const, }, payload: { diff --git a/src/commands/orchestrator/template/list.ts b/src/commands/orchestrator/template/list.ts index 8849e20..cf83bba 100644 --- a/src/commands/orchestrator/template/list.ts +++ b/src/commands/orchestrator/template/list.ts @@ -41,6 +41,11 @@ export default class ListTemplate extends SfCommand { summary: messages.getMessage('flags.api-version.summary'), description: messages.getMessage('flags.api-version.description'), }), + all: Flags.boolean({ + summary: messages.getMessage('flags.all.summary'), + description: messages.getMessage('flags.all.description'), + default: false, + }), }; public async run(): Promise { @@ -56,12 +61,18 @@ export default class ListTemplate extends SfCommand { const rawTemplates = await appFrameworkTemplate.list(); this.spinner.stop(); - const templates = TemplateListUtil.processTemplates(rawTemplates); + let templates = TemplateListUtil.processTemplates(rawTemplates); + + // Filter out standard templates by default unless --all flag is used + if (!flags.all) { + templates = templates.filter((template) => !template.name?.startsWith('sfdc_internal__')); + } if (templates.length > 0) { TemplateDisplayUtil.displayTemplateList(this, templates); } else { - this.log(messages.getMessage('noResultsFound')); + const messageKey = flags.all ? 'noResultsFound' : 'noCustomTemplatesFound'; + this.log(messages.getMessage(messageKey)); } return templates; diff --git a/test/commands/template/preview.nut.ts b/test/commands/orchestrator/rules/eval.nut.ts similarity index 82% rename from test/commands/template/preview.nut.ts rename to test/commands/orchestrator/rules/eval.nut.ts index 9389bca..4b9b864 100644 --- a/test/commands/template/preview.nut.ts +++ b/test/commands/orchestrator/rules/eval.nut.ts @@ -16,7 +16,7 @@ import { execCmd, TestSession } from '@salesforce/cli-plugins-testkit'; import { expect } from 'chai'; -describe('template preview NUTs', () => { +describe('rules eval NUTs', () => { let session: TestSession; before(async () => { @@ -27,10 +27,9 @@ describe('template preview NUTs', () => { await session?.clean(); }); - it('should display provided name', () => { - const name = 'World'; - const command = `template preview --name ${name}`; + it('should display help for rules eval', () => { + const command = 'orchestrator rules eval --help'; const output = execCmd(command, { ensureExitCode: 0 }).shellOutput.stdout; - expect(output).to.contain(name); + expect(output).to.contain('Test JSON transformation rules'); }); }); diff --git a/test/commands/template/preview.test.ts b/test/commands/orchestrator/rules/eval.test.ts similarity index 84% rename from test/commands/template/preview.test.ts rename to test/commands/orchestrator/rules/eval.test.ts index 5eee5a7..a3ca5b4 100644 --- a/test/commands/template/preview.test.ts +++ b/test/commands/orchestrator/rules/eval.test.ts @@ -15,9 +15,9 @@ */ import { TestContext } from '@salesforce/core/testSetup'; import { expect } from 'chai'; -import TemplateEval from '../../../src/commands/orchestrator/template/eval.js'; +import RulesEval from '../../../../src/commands/orchestrator/rules/eval.js'; -describe('template eval', () => { +describe('rules eval', () => { const $$ = new TestContext(); afterEach(() => { @@ -25,6 +25,6 @@ describe('template eval', () => { }); it('should exist and be importable', async () => { - expect(TemplateEval).to.exist; + expect(RulesEval).to.exist; }); }); From 370838a900388c28a66e69d748c9be6f91e5f362 Mon Sep 17 00:00:00 2001 From: Ricardo Viera Date: Fri, 5 Dec 2025 09:39:14 -0700 Subject: [PATCH 2/3] fix: update command snapshot for --all flag in template list --- command-snapshot.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command-snapshot.json b/command-snapshot.json index ba91427..b302871 100644 --- a/command-snapshot.json +++ b/command-snapshot.json @@ -108,7 +108,7 @@ "command": "orchestrator:template:list", "flagAliases": [], "flagChars": ["o"], - "flags": ["api-version", "flags-dir", "json", "target-org"], + "flags": ["all", "api-version", "flags-dir", "json", "target-org"], "plugin": "@salesforce/plugin-orchestrator" }, { From d5000cacccff7e84cee2fbdc371c1c2da36b1081 Mon Sep 17 00:00:00 2001 From: Ricardo Viera Date: Fri, 5 Dec 2025 09:42:34 -0700 Subject: [PATCH 3/3] chore: bump version to 1.1.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3ce1ed7..5c2da01 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@salesforce/plugin-orchestrator", "description": "Plugin for working with SalesForce analytic apps, templates, assets and services.", - "version": "1.0.19", + "version": "1.1.1", "author": "Salesforce", "bugs": "https://github.com/forcedotcom/cli/issues", "dependencies": {