@salesforce/afv-skills 1.55.0 → 1.57.0
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/package.json +1 -1
- package/skills/agentforce-generate/SKILL.md +8 -0
- package/skills/agentforce-generate/references/actions-reference.md +2 -2
- package/skills/agentforce-generate/references/voice-modality-reference.md +51 -15
- package/skills/agentforce-generate/references/voice-telephony-cli.md +193 -0
- package/skills/agentforce-observe/SKILL.md +13 -9
- package/skills/agentforce-observe/references/ahm-alerts.md +193 -14
- package/skills/automation-sandbox-post-copy-config-generate/SKILL.md +24 -15
- package/skills/automation-sandbox-post-copy-config-generate/assets/config_template.json +11 -0
- package/skills/automation-sandbox-post-copy-config-generate/assets/json_schema.json +33 -1
- package/skills/automation-sandbox-post-copy-config-generate/references/configuration_catalog.md +32 -1
- package/skills/automation-sandbox-post-copy-configure/SKILL.md +75 -71
- package/skills/automation-sandbox-post-copy-configure/assets/scheduled_apex_template.apex +13 -0
- package/skills/automation-sandbox-post-copy-configure/examples/sample_scheduled_apex_config.json +13 -0
- package/skills/automation-sandbox-post-copy-configure/references/scheduled_apex_path.md +155 -0
- package/skills/automation-sandbox-post-copy-configure/scripts/build-scheduled-apex.mjs +62 -0
- package/skills/automation-sandbox-post-copy-configure/scripts/soql-escape-job-name.mjs +28 -0
- package/skills/commerce-b2b-open-code-components-integrate/SKILL.md +1 -1
- package/skills/commerce-b2b-open-code-components-replace/SKILL.md +16 -16
- package/skills/consumer-goods-accruals-datakit-deploy/SKILL.md +383 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/setup.js +324 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/00-check-prerequisites.js +63 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/01-download-static-resource.js +100 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/02-replace-org-id.js +46 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/03-deploy-metadata.js +46 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/04-deploy-engine.js +198 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/05-deploy-tpm-accruals.js +231 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/06-create-dataspace.js +82 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/07-deploy-accruals-reports.js +517 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/08-deploy-ui.js +416 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/09-completion.js +44 -0
- package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/utils.js +514 -0
- package/skills/consumer-goods-sync-management-configure/SKILL.md +137 -0
- package/skills/consumer-goods-sync-management-configure/examples/scenarios.md +294 -0
- package/skills/consumer-goods-sync-management-configure/references/act1-setup-sync.md +333 -0
- package/skills/consumer-goods-sync-management-configure/references/act2-assign-users.md +324 -0
- package/skills/consumer-goods-sync-management-configure/references/act3-plan-verify.md +113 -0
- package/skills/consumer-goods-sync-management-configure/references/readiness-and-enablement.md +164 -0
- package/skills/consumer-goods-sync-management-configure/references/sync-management-app-install-backbone.md +159 -0
- package/skills/consumer-goods-sync-management-configure/references/transports-and-namespace.md +220 -0
- package/skills/consumer-goods-sync-management-configure/references/verify-and-smoke.md +175 -0
- package/skills/dx-devops-project-manage/SKILL.md +1 -1
- package/skills/dx-org-analyze/SKILL.md +0 -1
- package/skills/dx-org-analyze/scripts/collect_org_data.py +2 -2
- package/skills/dx-org-analyze/scripts/compute_diff.py +2 -4
- package/skills/dx-org-analyze/scripts/introspect_org.py +4 -40
- package/skills/dx-org-manage/SKILL.md +6 -50
- package/skills/dx-org-manage/examples/README.md +10 -16
- package/skills/dx-org-manage/references/scratch-org-create.md +1 -1
- package/skills/dx-org-manage/references/scratch-org-operations.md +1 -1
- package/skills/dx-org-shape-manage/SKILL.md +4 -3
- package/skills/education-cloud-domain-configure/references/gotchas-extended.md +1 -0
- package/skills/experience-accessibility-validate/SKILL.md +8 -5
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-1-1-non-text-content.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-i-lists.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-ii-tables.md +20 -85
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iii-form-labels.md +4 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-iv-regions.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-1-v-groups.md +2 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-3-5-identify-input.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-1-4-3-contrast.md +4 -14
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-1-1-keyboard.md +9 -5
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-4-link-purpose.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-4-6-headings-labels.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-1-pointer-gestures.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-2-pointer-cancellation.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-3-label-in-name.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-2-5-7-dragging-movement.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-2-1-on-focus.md +0 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-2-2-on-input.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-1-error-identification.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-2-labels-instructions.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-3-3-3-error-suggestion.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-i-name.md +4 -5
- package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-ii-role.md +1 -4
- package/skills/experience-accessibility-validate/references/reviewers/sc-4-1-2-iii-value.md +0 -4
- package/skills/experience-cms-content-generate/SKILL.md +1 -1
- package/skills/experience-cms-content-render/SKILL.md +3 -3
- package/skills/experience-cms-content-render/assets/angular/MediaRenderer.component.ts +35 -7
- package/skills/experience-cms-content-render/assets/angular/cms-item.service.ts +13 -4
- package/skills/experience-cms-content-render/assets/react/MediaRenderer.tsx +30 -8
- package/skills/experience-cms-content-render/assets/react/useCmsItem.ts +14 -4
- package/skills/experience-cms-content-render/assets/shared/cmsCore.types.ts +11 -1
- package/skills/experience-cms-content-render/assets/shared/externalRefs.ts +1 -1
- package/skills/experience-cms-content-render/assets/shared/mediaLabels.ts +62 -0
- package/skills/experience-cms-content-render/references/init-scaffold.md +13 -6
- package/skills/experience-content-media-stock-image-search/SKILL.md +0 -1
- package/skills/experience-lwc-accessibility-jest-run/SKILL.md +104 -25
- package/skills/experience-lwc-accessibility-jest-run/assets/jest.config.js +4 -0
- package/skills/experience-lwc-accessibility-jest-run/assets/sa11y-jest-setup.js +5 -0
- package/skills/experience-lwc-design-generate/SKILL.md +1 -1
- package/skills/experience-lwc-legacy-migrate/SKILL.md +212 -0
- package/skills/experience-lwc-legacy-migrate/assets/lo20-host-page-template.html +192 -0
- package/skills/experience-lwc-legacy-migrate/references/aura-to-lwc-completeness-checklist.md +188 -0
- package/skills/experience-lwc-legacy-migrate/references/lightning-out-2-system-reference.md +495 -0
- package/skills/experience-lwc-legacy-migrate/references/lightning-out-beta-to-2-migration.md +824 -0
- package/skills/experience-lwc-legacy-migrate/scripts/convert-lo-names.py +94 -0
- package/skills/experience-lwc-legacy-migrate/scripts/validate-lo20-page.py +133 -0
- package/skills/experience-ui-bundle-app-coordinate/SKILL.md +5 -5
- package/skills/experience-ui-bundle-features-generate/SKILL.md +65 -36
- package/skills/experience-ui-bundle-features-generate/references/angular/features.md +74 -0
- package/skills/experience-ui-bundle-features-generate/references/react/features.md +59 -0
- package/skills/experience-ui-bundle-features-generate/scripts/detect-framework.sh +73 -0
- package/skills/experience-ui-bundle-frontend-generate/SKILL.md +2 -2
- package/skills/experience-ui-bundle-metadata-generate/SKILL.md +26 -14
- package/skills/experience-ui-bundle-metadata-generate/references/angular-metadata-generate.md +37 -0
- package/skills/experience-ui-bundle-metadata-generate/references/react-metadata-generate.md +32 -0
- package/skills/experience-ui-bundle-metadata-generate/scripts/detect-framework.sh +73 -0
- package/skills/experience-ui-bundle-metadata-generate/scripts/verify-bundle-location.sh +30 -8
- package/skills/experience-ui-bundle-project-generate/SKILL.md +1 -1
- package/skills/field-service-data-capture-migrate/SKILL.md +391 -0
- package/skills/field-service-data-capture-migrate/assets/sample-legacy-flow.flow-meta.xml +163 -0
- package/skills/field-service-data-capture-migrate/references/architecture-notes.md +40 -0
- package/skills/field-service-data-capture-migrate/references/component-mapping.md +278 -0
- package/skills/field-service-data-capture-migrate/references/converter-builder-contract.md +183 -0
- package/skills/field-service-data-capture-migrate/references/dc-platform-rules.md +130 -0
- package/skills/field-service-data-capture-migrate/references/fsm-dc-capability-catalog.md +215 -0
- package/skills/field-service-data-capture-migrate/references/known-deploy-errors.md +36 -0
- package/skills/field-service-data-capture-migrate/references/migration-checklist.md +121 -0
- package/skills/field-service-data-capture-migrate/references/transformer-rules.md +132 -0
- package/skills/field-service-data-capture-migrate/scripts/analyze_flow.py +277 -0
- package/skills/field-service-data-capture-migrate/scripts/convert_to_dc_spec.py +1311 -0
- package/skills/field-service-data-capture-migrate/scripts/cud_analysis.py +402 -0
- package/skills/field-service-data-capture-migrate/scripts/deploy_flow.sh +230 -0
- package/skills/field-service-data-capture-migrate/scripts/discover_subflow_tree.py +230 -0
- package/skills/field-service-data-capture-migrate/scripts/flow_input.py +186 -0
- package/skills/field-service-data-capture-migrate/scripts/flow_xml_utils.py +39 -0
- package/skills/field-service-data-capture-migrate/scripts/fsm_dc_catalog.py +413 -0
- package/skills/field-service-data-capture-migrate/scripts/generate_summary.py +199 -0
- package/skills/field-service-data-capture-migrate/scripts/json_to_flow_xml.py +146 -0
- package/skills/field-service-data-capture-migrate/scripts/manual_review_flags.py +42 -0
- package/skills/field-service-data-capture-migrate/scripts/retrieve_flow_rest.sh +155 -0
- package/skills/field-service-data-capture-migrate/scripts/subflow_names.py +49 -0
- package/skills/field-service-data-capture-migrate/scripts/transform_flow.py +1661 -0
- package/skills/field-service-data-capture-migrate/scripts/validate_flow.sh +147 -0
- package/skills/field-service-data-capture-migrate/scripts/vendor/build_flow.py +1258 -0
- package/skills/integration-connectivity-connected-app-configure/SKILL.md +5 -5
- package/skills/integration-connectivity-generate/SKILL.md +10 -10
- package/skills/integration-connectivity-generate/scripts/configure-named-credential.sh +2 -2
- package/skills/life-sciences-fieldsalesrep-coordinate/SKILL.md +1 -1
- package/skills/life-sciences-fieldsalesrep-coordinate/references/orchestration-flow.md +1 -1
- package/skills/life-sciences-kam-coordinate/references/stage-5-data-and-plan-templates-overview.md +14 -1
- package/skills/mobile-apps-create/SKILL.md +1 -1
- package/skills/{platform-agentsetup-categories-fetch → platform-agenticsetup-categories-get}/SKILL.md +7 -7
- package/skills/platform-apex-test-generate/SKILL.md +1 -1
- package/skills/platform-apex-test-run/SKILL.md +1 -1
- package/skills/platform-custom-field-generate/SKILL.md +1 -1
- package/skills/platform-custom-lightning-type-generate/SKILL.md +1 -1
- package/skills/platform-custom-metadata-type-generate/SKILL.md +1 -1
- package/skills/platform-custom-object-generate/SKILL.md +1 -1
- package/skills/platform-custom-report-type-generate/SKILL.md +1 -1
- package/skills/platform-custom-setting-generate/SKILL.md +1 -1
- package/skills/platform-data-and-tooling-api-context-get/SKILL.md +1 -1
- package/skills/platform-data-manage/SKILL.md +10 -10
- package/skills/platform-flexipage-generate/SKILL.md +1 -1
- package/skills/platform-lightning-app-coordinate/SKILL.md +1 -1
- package/skills/platform-metadata-api-context-get/SKILL.md +1 -1
- package/skills/platform-metadata-retrieve/SKILL.md +1 -1
- package/skills/platform-permission-set-generate/SKILL.md +1 -1
- package/skills/platform-report-generate/SKILL.md +1 -1
- package/skills/platform-salesforce-connect-adapter-generate/SKILL.md +4 -4
- package/skills/platform-sandbox-configure/SKILL.md +108 -133
- package/skills/platform-sandbox-configure/references/api-response-shapes.md +39 -0
- package/skills/platform-sandbox-configure/references/definition-file-approach.md +73 -0
- package/skills/platform-sharing-owd-configure/SKILL.md +1 -1
- package/skills/platform-sharing-rules-generate/SKILL.md +1 -1
- package/skills/platform-soql-query/SKILL.md +1 -1
- package/skills/platform-value-set-generate/SKILL.md +1 -1
- package/skills/platform-widget-generate/SKILL.md +26 -18
- package/skills/platform-widget-generate/examples/formulas.json +191 -0
- package/skills/platform-widget-generate/references/widget-formulas.md +123 -0
- package/skills/platform-widget-generate/references/widget-meta-directives.md +4 -4
- package/skills/sales-call-scoring-configure/SKILL.md +318 -0
- package/skills/sales-call-scoring-configure/assets/best-practice-competencies.json +67 -0
- package/skills/sales-call-scoring-configure/assets/ootb-competencies.json +58 -0
- package/skills/sales-call-scoring-configure/references/admin-communication.md +79 -0
- package/skills/sales-call-scoring-configure/references/competency-crud.md +130 -0
- package/skills/sales-call-scoring-configure/scripts/create-competency.sh +166 -0
- package/skills/sales-call-scoring-configure/scripts/create-custom-competency.sh +166 -0
- package/skills/sales-call-scoring-configure/scripts/edit-competency.sh +185 -0
- package/skills/sales-call-scoring-configure/scripts/edit-custom-competency.sh +190 -0
- package/skills/sales-call-scoring-configure/scripts/enable-call-scoring.sh +436 -0
- package/skills/sales-call-scoring-configure/scripts/get-competency.sh +72 -0
- package/skills/sales-call-scoring-configure/scripts/get-custom-competency.sh +78 -0
- package/skills/sales-call-scoring-configure/scripts/install-best-practice-competencies.sh +223 -0
- package/skills/sales-call-scoring-configure/scripts/install-ootb-competencies.sh +237 -0
- package/skills/sales-call-scoring-configure/scripts/list-competencies.sh +99 -0
- package/skills/sales-call-scoring-configure/scripts/shared/auth.sh +116 -0
- package/skills/sales-call-scoring-configure/scripts/shared/cap.sh +86 -0
- package/skills/sales-call-scoring-configure/scripts/shared/soap.sh +267 -0
- package/skills/sales-call-scoring-configure/scripts/shared/soql.sh +25 -0
- package/skills/sales-call-scoring-configure/scripts/toggle-competency.sh +112 -0
- package/skills/sales-call-scoring-configure/scripts/toggle-custom-competency.sh +125 -0
- package/skills/sales-call-scoring-configure/scripts/verify-ootb-competencies.sh +116 -0
- package/skills/service-agentforce-human-escalation-configure/SKILL.md +4 -0
- package/skills/service-agentforce-human-escalation-configure/scripts/tests/_bootstrap.py +26 -6
- package/skills/service-agentforce-human-escalation-configure/scripts/tests/test_escalation_contracts.py +5 -4
- package/skills/service-concierge-portal-generate/references/portal-deploy-runbook.md +1 -0
- package/skills/service-de-channel-activate/SKILL.md +6 -5
- package/skills/service-de-channel-create/SKILL.md +3 -3
- package/skills/service-de-channel-routing-configure/SKILL.md +3 -3
- package/skills/service-de-channel-settings-configure/SKILL.md +195 -0
- package/skills/service-de-channel-settings-configure/references/channel-settings-facets.md +152 -0
- package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/gotchas.md +3 -3
- package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/language-keywords.md +4 -4
- package/skills/{service-de-channel-consent-configure → service-de-channel-settings-configure}/references/worked-examples.md +14 -14
- package/skills/service-de-headless-channel-configure/SKILL.md +6 -6
- package/skills/service-de-headless-channel-configure/references/worked-examples.md +1 -1
- package/skills/service-de-waba-integrate/SKILL.md +2 -1
- package/skills/service-digital-engagement-deployment-configure/SKILL.md +2 -0
- package/skills/service-digital-engagement-deployment-configure/scripts/check-api-version.sh +29 -0
- package/skills/service-email-to-case-configure/SKILL.md +1 -1
- package/skills/service-helpagent-coordinate/SKILL.md +3 -2
- package/skills/service-helpagent-coordinate/references/channel-voice.md +15 -4
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/SKILL.md +49 -31
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/examples/output-templates.md +71 -6
- package/skills/service-itsm-agentic-setup-agentforce-coordinate/scripts/verify-child-verdict.mjs +26 -4
- package/skills/service-itsm-agentic-setup-cmdb-access-assign/SKILL.md +35 -10
- package/skills/service-itsm-agentic-setup-cmdb-access-assign/references/mcp-invocation.md +25 -5
- package/skills/service-itsm-agentic-setup-cmdb-bundle-deploy/SKILL.md +1 -1
- package/skills/service-itsm-agentic-setup-cmdb-configure/SKILL.md +5 -5
- package/skills/service-itsm-agentic-setup-cmdb-configure/references/mcp-invocation.md +1 -1
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/SKILL.md +2 -2
- package/skills/service-itsm-agentic-setup-cmdb-coordinate/examples/output-templates.md +1 -1
- package/skills/service-itsm-agentic-setup-cmdb-discovery-configure/SKILL.md +25 -15
- package/skills/service-itsm-agentic-setup-employee-agent-configure/SKILL.md +8 -5
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/report-format.md +4 -2
- package/skills/service-itsm-agentic-setup-employee-agent-configure/references/workflow-detail.md +1 -1
- package/skills/service-itsm-agentic-setup-employee-agent-configure/scripts/render-report.mjs +29 -16
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/SKILL.md +8 -5
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/report-format.md +4 -2
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/references/workflow-detail.md +1 -1
- package/skills/service-itsm-agentic-setup-fulfiller-agent-configure/scripts/render-report.mjs +29 -16
- package/skills/service-itsm-agentic-setup-incident-management/SKILL.md +138 -68
- package/skills/service-itsm-agentic-setup-incident-management/examples/output-templates.md +31 -15
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-persona-psg.md +156 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/incident-preferences.md +148 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/major-incident-management.md +162 -0
- package/skills/service-itsm-agentic-setup-incident-management/references/service-mgmt-privilege.md +149 -0
- package/skills/service-itsm-agentic-setup-incident-sla-configure/SKILL.md +103 -89
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/attach-milestone.json +2 -2
- package/skills/service-itsm-agentic-setup-incident-sla-configure/assets/predefined-incident-policy.json +21 -39
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/milestone-patterns.md +3 -3
- package/skills/service-itsm-agentic-setup-incident-sla-configure/examples/output-templates.md +18 -1
- package/skills/service-itsm-agentic-setup-incident-sla-configure/references/mcp-invocation.md +63 -37
- package/skills/service-omni-attribute-routing-configure/SKILL.md +53 -0
- package/skills/service-omni-attribute-routing-configure/references/api-notes.md +7 -0
- package/skills/service-omni-attribute-routing-configure/scripts/configure-and-report.sh +224 -0
- package/skills/service-omni-attribute-routing-configure/scripts/tests/test_attribute_routing_contracts.py +137 -0
- package/skills/service-omni-channel-inventory-analyze/SKILL.md +96 -0
- package/skills/service-omni-channel-inventory-analyze/references/api-notes.md +52 -0
- package/skills/service-omni-channel-inventory-analyze/scripts/analyze.sh +185 -0
- package/skills/service-omni-channel-inventory-analyze/scripts/tests/_bootstrap.py +84 -0
- package/skills/service-omni-channel-inventory-analyze/scripts/tests/test_inventory_analyze_contracts.py +141 -0
- package/skills/service-omni-channel-limits-analyze/SKILL.md +70 -0
- package/skills/service-omni-channel-limits-analyze/references/api-notes.md +22 -0
- package/skills/service-omni-channel-limits-analyze/scripts/analyze.sh +159 -0
- package/skills/service-omni-channel-limits-analyze/scripts/tests/_bootstrap.py +87 -0
- package/skills/service-omni-channel-limits-analyze/scripts/tests/test_limits_analyze_contracts.py +99 -0
- package/skills/service-omni-channel-setup-coordinate/SKILL.md +12 -20
- package/skills/service-omni-channel-setup-coordinate/scripts/integration-driver.sh +55 -5
- package/skills/service-omni-channel-setup-coordinate/scripts/tests/test_omni_contracts.py +38 -0
- package/skills/service-omni-command-center-analyze/SKILL.md +2 -2
- package/skills/service-omni-command-center-analyze/scripts/analyze.sh +3 -3
- package/skills/dx-org-manage/examples/snapshots/error_output.json +0 -9
- package/skills/dx-org-manage/examples/snapshots/success_output.json +0 -15
- package/skills/dx-org-manage/references/cli_flags.md +0 -67
- package/skills/dx-org-manage/references/creating-snapshot.md +0 -103
- package/skills/dx-org-manage/references/snapshot_usage.md +0 -74
- package/skills/experience-accessibility-validate/scripts/contrast-ratio.py +0 -153
- package/skills/experience-lwc-accessibility-jest-run/references/running-sa11y-jest-tests.md +0 -205
- package/skills/experience-ui-bundle-features-generate/scripts/verify-react-bundle.sh +0 -14
- /package/skills/experience-ui-bundle-features-generate/references/{conflict-resolution-schema.json → common/conflict-resolution-schema.json} +0 -0
- /package/skills/{platform-agentsetup-categories-fetch → platform-agenticsetup-categories-get}/references/api-response-schema.md +0 -0
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { getOrgDetails, getOrgNamespace } = require('./steps/utils');
|
|
5
|
+
|
|
6
|
+
// Import all step modules
|
|
7
|
+
const checkPrerequisites = require('./steps/00-check-prerequisites');
|
|
8
|
+
const downloadStaticResource = require('./steps/01-download-static-resource');
|
|
9
|
+
const replaceOrgId = require('./steps/02-replace-org-id');
|
|
10
|
+
const deployMetadata = require('./steps/03-deploy-metadata');
|
|
11
|
+
const deployEngine = require('./steps/04-deploy-engine');
|
|
12
|
+
const deployTPMAccruals = require('./steps/05-deploy-tpm-accruals');
|
|
13
|
+
const createDataSpace = require('./steps/06-create-dataspace');
|
|
14
|
+
const deployAccrualsReports = require('./steps/07-deploy-accruals-reports');
|
|
15
|
+
const deployUI = require('./steps/08-deploy-ui');
|
|
16
|
+
const completion = require('./steps/09-completion');
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Parse command line arguments
|
|
20
|
+
* Supports both flags (--flag=value, --flag value, -f value) and positional arguments
|
|
21
|
+
* @returns {{ orgAlias: string|null, skipDataSpace: boolean, salesOrg: string, dryRun: boolean, namespace: string|null }}
|
|
22
|
+
*/
|
|
23
|
+
function parseArgs() {
|
|
24
|
+
const args = process.argv.slice(2);
|
|
25
|
+
const result = {
|
|
26
|
+
orgAlias: null,
|
|
27
|
+
skipDataSpace: false,
|
|
28
|
+
salesOrg: null,
|
|
29
|
+
dryRun: false,
|
|
30
|
+
namespace: null,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
for (let i = 0; i < args.length; i++) {
|
|
34
|
+
const arg = args[i];
|
|
35
|
+
|
|
36
|
+
// Handle --flag=value format
|
|
37
|
+
if (arg.includes('=')) {
|
|
38
|
+
const [key, value] = arg.split('=');
|
|
39
|
+
switch (key) {
|
|
40
|
+
case '--org':
|
|
41
|
+
case '-o':
|
|
42
|
+
result.orgAlias = value;
|
|
43
|
+
break;
|
|
44
|
+
case '--sales-org':
|
|
45
|
+
case '-s':
|
|
46
|
+
result.salesOrg = value;
|
|
47
|
+
break;
|
|
48
|
+
case '--skip-dataspace':
|
|
49
|
+
result.skipDataSpace = value === 'true';
|
|
50
|
+
break;
|
|
51
|
+
case '--dry-run':
|
|
52
|
+
result.dryRun = value === 'true';
|
|
53
|
+
break;
|
|
54
|
+
case '--namespace':
|
|
55
|
+
case '-n':
|
|
56
|
+
result.namespace = value;
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Handle --flag value format and boolean flags
|
|
63
|
+
switch (arg) {
|
|
64
|
+
case '--org':
|
|
65
|
+
case '-o':
|
|
66
|
+
result.orgAlias = args[++i];
|
|
67
|
+
break;
|
|
68
|
+
case '--sales-org':
|
|
69
|
+
case '-s':
|
|
70
|
+
result.salesOrg = args[++i];
|
|
71
|
+
break;
|
|
72
|
+
case '--skip-dataspace':
|
|
73
|
+
result.skipDataSpace = true;
|
|
74
|
+
break;
|
|
75
|
+
case '--dry-run':
|
|
76
|
+
case '-d':
|
|
77
|
+
result.dryRun = true;
|
|
78
|
+
break;
|
|
79
|
+
case '--namespace':
|
|
80
|
+
case '-n':
|
|
81
|
+
result.namespace = args[++i];
|
|
82
|
+
break;
|
|
83
|
+
case '--help':
|
|
84
|
+
case '-h':
|
|
85
|
+
printHelp();
|
|
86
|
+
process.exit(0);
|
|
87
|
+
break;
|
|
88
|
+
default:
|
|
89
|
+
// Positional argument (org alias for backward compatibility)
|
|
90
|
+
if (!arg.startsWith('-') && !result.orgAlias) {
|
|
91
|
+
result.orgAlias = arg;
|
|
92
|
+
}
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Print help message
|
|
102
|
+
*/
|
|
103
|
+
function printHelp() {
|
|
104
|
+
console.log(`
|
|
105
|
+
Usage: node setup.js [options] [org-alias]
|
|
106
|
+
|
|
107
|
+
Options:
|
|
108
|
+
-o, --org <alias> Salesforce org alias (can also use SF_ORG_ALIAS env var)
|
|
109
|
+
-s, --sales-org <org> Sales org identifier (required; can also use SALES_ORG env var)
|
|
110
|
+
-n, --namespace <ns> Org namespace prefix WITHOUT trailing "__" (e.g. "cgcloud_dev").
|
|
111
|
+
If omitted, the namespace is auto-detected from the org.
|
|
112
|
+
Use empty string ("") to force unmanaged behavior.
|
|
113
|
+
--skip-dataspace Skip Data Space creation (can also use SKIP_DATASPACE=true env var)
|
|
114
|
+
-d, --dry-run Show what would be done without making any changes
|
|
115
|
+
-h, --help Show this help message
|
|
116
|
+
|
|
117
|
+
Examples:
|
|
118
|
+
node setup.js --org my-org --sales-org 0001
|
|
119
|
+
node setup.js --org my-org --sales-org 0002
|
|
120
|
+
node setup.js -o my-org -s 0002 --skip-dataspace
|
|
121
|
+
node setup.js --dry-run --org my-org --sales-org 0001
|
|
122
|
+
node setup.js --org my-org --namespace cgcloud_dev
|
|
123
|
+
|
|
124
|
+
Environment variables:
|
|
125
|
+
SF_ORG_ALIAS Salesforce org alias
|
|
126
|
+
SALES_ORG Sales org identifier (required)
|
|
127
|
+
SKIP_DATASPACE Set to "true" to skip Data Space creation
|
|
128
|
+
DRY_RUN Set to "true" for dry run mode
|
|
129
|
+
ORG_NAMESPACE Org namespace prefix WITHOUT trailing "__" (overrides auto-detection)
|
|
130
|
+
`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Get configuration from CLI args and environment variables
|
|
135
|
+
* CLI args take precedence over environment variables
|
|
136
|
+
* @returns {{ orgAlias: string, skipDataSpace: boolean, salesOrg: string, dryRun: boolean, namespaceOverride: string|null }}
|
|
137
|
+
*/
|
|
138
|
+
function getConfig() {
|
|
139
|
+
const cliArgs = parseArgs();
|
|
140
|
+
|
|
141
|
+
// CLI args take precedence over environment variables
|
|
142
|
+
const orgAlias = cliArgs.orgAlias || process.env.SF_ORG_ALIAS;
|
|
143
|
+
const skipDataSpace = cliArgs.skipDataSpace || process.env.SKIP_DATASPACE === 'true';
|
|
144
|
+
const salesOrg = cliArgs.salesOrg || process.env.SALES_ORG || null;
|
|
145
|
+
const dryRun = cliArgs.dryRun || process.env.DRY_RUN === 'true';
|
|
146
|
+
|
|
147
|
+
// namespaceOverride is null when neither CLI nor env was provided (=> auto-detect),
|
|
148
|
+
// or a string (possibly empty) when the user explicitly specified one.
|
|
149
|
+
let namespaceOverride = null;
|
|
150
|
+
if (cliArgs.namespace !== null && cliArgs.namespace !== undefined) {
|
|
151
|
+
namespaceOverride = cliArgs.namespace;
|
|
152
|
+
} else if (process.env.ORG_NAMESPACE !== undefined) {
|
|
153
|
+
namespaceOverride = process.env.ORG_NAMESPACE;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (!orgAlias) {
|
|
157
|
+
console.error('Error: Org alias not provided.');
|
|
158
|
+
console.error('Usage: node setup.js <org-alias>');
|
|
159
|
+
console.error(' OR: node setup.js --org <org-alias>');
|
|
160
|
+
console.error(' OR: SF_ORG_ALIAS=<org-alias> node setup.js');
|
|
161
|
+
console.error('\nRun "node setup.js --help" for more options.');
|
|
162
|
+
process.exit(1);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (!salesOrg) {
|
|
166
|
+
console.error('Error: Sales org not provided.');
|
|
167
|
+
console.error('Usage: node setup.js --sales-org <value>');
|
|
168
|
+
console.error(' OR: SALES_ORG=<value> node setup.js');
|
|
169
|
+
console.error('\nRun "node setup.js --help" for available options.');
|
|
170
|
+
process.exit(1);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return { orgAlias, skipDataSpace, salesOrg, dryRun, namespaceOverride };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Validate salesOrg and namespaceOverride inputs.
|
|
178
|
+
* Exits the process with an error message if validation fails.
|
|
179
|
+
* @param {string} salesOrg - Must be exactly 4 alphanumeric characters.
|
|
180
|
+
* @param {string|null} namespaceOverride - When non-null, must be 1-15 alphanumeric characters.
|
|
181
|
+
*/
|
|
182
|
+
function validateInputs(salesOrg, namespaceOverride, orgAlias) {
|
|
183
|
+
// Org alias: Salesforce allows alphanumeric, hyphens, underscores, dots, and @ (usernames).
|
|
184
|
+
// Restrict to safe characters to prevent shell metacharacter injection on Windows cmd.exe.
|
|
185
|
+
// Allow alphanumeric, hyphens, underscores, dots, @, and + (valid in Salesforce usernames, e.g. user+ci@example.com).
|
|
186
|
+
// None of these characters are cmd.exe metacharacters, so shell injection via org alias is prevented.
|
|
187
|
+
if (!/^[A-Za-z0-9_\-@.+]+$/.test(orgAlias)) {
|
|
188
|
+
console.error(`Error: Invalid org alias "${orgAlias}". Must contain only alphanumeric characters, hyphens, underscores, dots, @, or +.`);
|
|
189
|
+
process.exit(1);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (!/^[A-Za-z0-9]{4}$/.test(salesOrg)) {
|
|
193
|
+
console.error('Error: Invalid sales org.');
|
|
194
|
+
process.exit(1);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (namespaceOverride !== null && namespaceOverride !== '' && !/^[A-Za-z0-9]{1,15}$/.test(namespaceOverride)) {
|
|
198
|
+
console.error('Error: Invalid namespace.');
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Format a namespace value into the prefix form used in metadata
|
|
205
|
+
* (i.e. always ends with "__", or is the empty string).
|
|
206
|
+
*/
|
|
207
|
+
function formatNamespace(value) {
|
|
208
|
+
if (!value) return '';
|
|
209
|
+
return value.endsWith('__') ? value : `${value}__`;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Derive Data Space name and prefix from sales org
|
|
214
|
+
* @param {string} salesOrg - The sales org value
|
|
215
|
+
* @returns {{ dataSpaceName: string, dataSpacePrefix: string }}
|
|
216
|
+
*/
|
|
217
|
+
function getDataSpaceConfig(salesOrg) {
|
|
218
|
+
const lastChar = salesOrg.slice(-1);
|
|
219
|
+
return {
|
|
220
|
+
dataSpaceName: `DataSpace_${salesOrg}`,
|
|
221
|
+
dataSpacePrefix: `DS${lastChar}_`,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Main setup function
|
|
227
|
+
*/
|
|
228
|
+
async function main() {
|
|
229
|
+
console.log('=== Salesforce Org Setup ===\n');
|
|
230
|
+
|
|
231
|
+
const config = getConfig();
|
|
232
|
+
const { orgAlias, skipDataSpace, salesOrg, dryRun, namespaceOverride } = config;
|
|
233
|
+
|
|
234
|
+
// Validate inputs before any org access or step execution
|
|
235
|
+
validateInputs(salesOrg, namespaceOverride, orgAlias);
|
|
236
|
+
|
|
237
|
+
const { dataSpaceName, dataSpacePrefix } = getDataSpaceConfig(salesOrg);
|
|
238
|
+
|
|
239
|
+
if (dryRun) {
|
|
240
|
+
console.log('+============================================================================+');
|
|
241
|
+
console.log('| DRY RUN MODE |');
|
|
242
|
+
console.log('| All read-only steps will execute. Deployments to org will be skipped. |');
|
|
243
|
+
console.log('| Temp directories will be preserved for inspection. |');
|
|
244
|
+
console.log('+============================================================================+\n');
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
console.log(`Target org: ${orgAlias}`);
|
|
248
|
+
|
|
249
|
+
// Verify org is accessible and get org details
|
|
250
|
+
console.log('Verifying org connection...');
|
|
251
|
+
let orgId;
|
|
252
|
+
try {
|
|
253
|
+
const orgDetails = getOrgDetails(orgAlias);
|
|
254
|
+
orgId = orgDetails.orgId;
|
|
255
|
+
console.log(`[OK] Org connection verified (Org ID: ${orgId})\n`);
|
|
256
|
+
} catch (error) {
|
|
257
|
+
console.error(`Error: Cannot connect to org "${orgAlias}"`);
|
|
258
|
+
console.error('Make sure you are logged in via: sf org login web');
|
|
259
|
+
process.exit(1);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Resolve org namespace: CLI/env override wins; otherwise query the org.
|
|
263
|
+
// This is needed because component names in DataKitDeploymentLog and field
|
|
264
|
+
// references in the Accruals Reports payload can carry a namespace prefix
|
|
265
|
+
// depending on the org (e.g. "cgcloud_dev__" in this repo's dev org).
|
|
266
|
+
let namespace;
|
|
267
|
+
if (namespaceOverride !== null && namespaceOverride !== undefined) {
|
|
268
|
+
namespace = formatNamespace(namespaceOverride);
|
|
269
|
+
console.log(`Using namespace override: "${namespace || '(none)'}"`);
|
|
270
|
+
} else {
|
|
271
|
+
console.log('Detecting org namespace...');
|
|
272
|
+
namespace = getOrgNamespace(orgAlias);
|
|
273
|
+
console.log(`Detected namespace: "${namespace || '(none)'}"`);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const setupDir = __dirname;
|
|
277
|
+
|
|
278
|
+
console.log(`Sales Org: ${salesOrg}`);
|
|
279
|
+
if (!skipDataSpace) {
|
|
280
|
+
console.log(`Data Space Name: ${dataSpaceName}`);
|
|
281
|
+
console.log(`Data Space Prefix: ${dataSpacePrefix}\n`);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// Step 0: Check Prerequisites (skip in dry run)
|
|
285
|
+
if (!dryRun) {
|
|
286
|
+
await checkPrerequisites();
|
|
287
|
+
} else {
|
|
288
|
+
console.log('\n=== Step 0: Check Prerequisites (skipped in dry run) ===\n');
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Run all steps in order
|
|
292
|
+
// Step 1 returns the extraction dir; derive dataKitPath and scriptsDir from it.
|
|
293
|
+
const cgcloudAddonsDir = await downloadStaticResource(orgAlias, setupDir);
|
|
294
|
+
const dataKitPath = path.join(cgcloudAddonsDir, 'TPM', 'Accruals', 'TPM Accruals Data Kit');
|
|
295
|
+
const scriptsDir = path.join(cgcloudAddonsDir, 'TPM', 'Accruals', 'Accruals Data Kit Deployment Scripts');
|
|
296
|
+
await replaceOrgId(orgId, dataKitPath);
|
|
297
|
+
await deployMetadata(orgAlias, dataKitPath, dryRun);
|
|
298
|
+
await deployEngine(orgAlias, scriptsDir, orgId, namespace, dryRun);
|
|
299
|
+
await deployTPMAccruals(orgAlias, scriptsDir, dataKitPath, orgId, namespace, dryRun);
|
|
300
|
+
|
|
301
|
+
// Step 6: Create Data Space (only if Data Spaces are available)
|
|
302
|
+
if (!skipDataSpace) {
|
|
303
|
+
await createDataSpace(orgAlias, salesOrg, dataSpaceName, dataSpacePrefix, dryRun);
|
|
304
|
+
} else {
|
|
305
|
+
console.log('\n=== Step 6: Skipping Data Space creation (--skip-dataspace) ===\n');
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// Step 7: Deploy Accruals Reports with Data Space replacements
|
|
309
|
+
await deployAccrualsReports(orgAlias, cgcloudAddonsDir, skipDataSpace, dataSpaceName, dataSpacePrefix, namespace, dryRun);
|
|
310
|
+
|
|
311
|
+
// Step 8: Deploy UI components (TPMAccrualTacticSummary)
|
|
312
|
+
await deployUI(orgAlias, cgcloudAddonsDir, skipDataSpace, dataSpaceName, dataSpacePrefix, salesOrg, namespace, dryRun);
|
|
313
|
+
|
|
314
|
+
// Step 9: Completion and next steps
|
|
315
|
+
await completion(dryRun);
|
|
316
|
+
|
|
317
|
+
console.log('=== Setup completed successfully ===');
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Run the script
|
|
321
|
+
main().catch(error => {
|
|
322
|
+
console.error('Unexpected error:', error);
|
|
323
|
+
process.exit(1);
|
|
324
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const readline = require('readline');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Step 0: Check Prerequisites
|
|
5
|
+
* Presents prerequisites to the user and waits for confirmation
|
|
6
|
+
*/
|
|
7
|
+
async function checkPrerequisites() {
|
|
8
|
+
console.log('\n=== Step 0: Prerequisites ===');
|
|
9
|
+
|
|
10
|
+
console.log('\nBefore proceeding, confirm ALL of the following are complete in your org.\n');
|
|
11
|
+
|
|
12
|
+
console.log('--- PERMISSIONS ---');
|
|
13
|
+
console.log('\n1. Assign permission set "Data Cloud Architect" to:');
|
|
14
|
+
console.log(' - The System Admin user');
|
|
15
|
+
console.log(' - The user assigned to the Accrual Ingestion Process');
|
|
16
|
+
console.log('\n2. Enable CRM Analytics (if you need Accruals dashboards):');
|
|
17
|
+
console.log(' Setup > Feature Settings > Analytics > Analytics > Getting Started > Enable CRM Analytics');
|
|
18
|
+
console.log(' Then assign permission set "CRM Analytics Plus Admin" to the System Admin.');
|
|
19
|
+
|
|
20
|
+
console.log('\n--- DATA CLOUD ---');
|
|
21
|
+
console.log('\n3. Data Cloud is enabled and set up (via the Data Cloud app, not Setup).');
|
|
22
|
+
console.log('\n4. Salesforce CRM connector is active:');
|
|
23
|
+
console.log(' Data Cloud app > Data Cloud Setup > Salesforce CRM > enable Home Org connection.');
|
|
24
|
+
console.log(' Also activate any other required connectors using the dropdown button.');
|
|
25
|
+
console.log('\n5. A user is assigned to the Accrual Ingestion Process:');
|
|
26
|
+
console.log(' Setup > Processing Services Pairing > Accrual Ingestion Process.');
|
|
27
|
+
|
|
28
|
+
console.log('\n--- INTEGRATION ---');
|
|
29
|
+
console.log('\n6. OAuth scope "cdp_ingest_api" is configured on the integration app used by TPM Offcore.');
|
|
30
|
+
console.log(' Check Setup > App Manager (Connected Apps) or Setup > External Client Apps.');
|
|
31
|
+
console.log(' The app name varies by org — locate the one used by TPM Offcore.');
|
|
32
|
+
|
|
33
|
+
console.log('\n');
|
|
34
|
+
|
|
35
|
+
// Wait for user confirmation
|
|
36
|
+
await waitForUserConfirmation();
|
|
37
|
+
|
|
38
|
+
console.log('[OK] Prerequisites confirmed. Proceeding to next step...\n');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Wait for user to press Enter.
|
|
43
|
+
* Auto-confirms immediately when stdin is not a TTY (piped / headless run).
|
|
44
|
+
*/
|
|
45
|
+
function waitForUserConfirmation() {
|
|
46
|
+
if (!process.stdin.isTTY) {
|
|
47
|
+
console.log('[Auto-confirmed: running non-interactively]');
|
|
48
|
+
return Promise.resolve();
|
|
49
|
+
}
|
|
50
|
+
return new Promise((resolve) => {
|
|
51
|
+
const rl = readline.createInterface({
|
|
52
|
+
input: process.stdin,
|
|
53
|
+
output: process.stdout
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
rl.question('Press Enter when you have confirmed all prerequisites are met...', () => {
|
|
57
|
+
rl.close();
|
|
58
|
+
resolve();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
module.exports = checkPrerequisites;
|
package/skills/consumer-goods-accruals-datakit-deploy/scripts/steps/01-download-static-resource.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const https = require('https');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { execFileSync } = require('child_process');
|
|
6
|
+
const { execSfJson, getOrgDetails } = require('./utils');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Step 1: Download and extract the CGCloudAddons static resource
|
|
10
|
+
*/
|
|
11
|
+
async function downloadStaticResource(orgAlias, setupDir) {
|
|
12
|
+
console.log('\n=== Step 1: Downloading CGCloudAddons static resource ===');
|
|
13
|
+
|
|
14
|
+
const staticResourceName = 'CGCloudAddons';
|
|
15
|
+
// Extract to os.tmpdir() to avoid EBUSY locks in the script tree on Windows
|
|
16
|
+
const extractBase = path.join(os.tmpdir(), `tpm_accruals_extract_${Date.now()}`);
|
|
17
|
+
|
|
18
|
+
// Get org details for REST API call
|
|
19
|
+
console.log('Getting org connection details...');
|
|
20
|
+
const orgDetails = getOrgDetails(orgAlias);
|
|
21
|
+
|
|
22
|
+
// Query for the static resource
|
|
23
|
+
console.log(`Looking up ${staticResourceName} in org...`);
|
|
24
|
+
const queryResult = execSfJson(['data', 'query', '--query', `SELECT Id, Name FROM StaticResource WHERE Name = '${staticResourceName}'`, '--target-org', orgAlias, '--json']);
|
|
25
|
+
|
|
26
|
+
if (queryResult.status !== 0 || !queryResult.result.records || queryResult.result.records.length === 0) {
|
|
27
|
+
console.error(`Error: Static resource ${staticResourceName} not found in org`);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const staticResourceId = queryResult.result.records[0].Id;
|
|
32
|
+
console.log(`Found ${staticResourceName} (ID: ${staticResourceId})`);
|
|
33
|
+
|
|
34
|
+
// Download the static resource body using REST API
|
|
35
|
+
console.log('Downloading static resource content...');
|
|
36
|
+
fs.mkdirSync(extractBase, { recursive: true });
|
|
37
|
+
const targetFile = path.join(extractBase, `${staticResourceName}.zip`);
|
|
38
|
+
const bodyUrl = `${orgDetails.instanceUrl}/services/data/v${orgDetails.apiVersion}/sobjects/StaticResource/${staticResourceId}/Body`;
|
|
39
|
+
|
|
40
|
+
await new Promise((resolve, reject) => {
|
|
41
|
+
const url = new URL(bodyUrl);
|
|
42
|
+
const req = https.get({
|
|
43
|
+
hostname: url.hostname,
|
|
44
|
+
path: url.pathname + url.search,
|
|
45
|
+
headers: { Authorization: `Bearer ${orgDetails.accessToken}` }
|
|
46
|
+
}, res => {
|
|
47
|
+
if (res.statusCode !== 200) {
|
|
48
|
+
reject(new Error(`HTTP ${res.statusCode} downloading static resource`));
|
|
49
|
+
res.resume();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const out = fs.createWriteStream(targetFile);
|
|
53
|
+
res.pipe(out);
|
|
54
|
+
out.on('finish', resolve);
|
|
55
|
+
out.on('error', reject);
|
|
56
|
+
});
|
|
57
|
+
req.on('error', reject);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (!fs.existsSync(targetFile)) {
|
|
61
|
+
console.error('Error: Failed to download static resource');
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
console.log(`Static resource saved to: ${targetFile}`);
|
|
66
|
+
|
|
67
|
+
// Extract the zip file
|
|
68
|
+
console.log('Extracting static resource...');
|
|
69
|
+
const extractDir = path.join(extractBase, staticResourceName);
|
|
70
|
+
fs.mkdirSync(extractDir, { recursive: true });
|
|
71
|
+
|
|
72
|
+
// Extract: use Windows System32 bsdtar on Windows (Git Bash's GNU tar cannot
|
|
73
|
+
// read ZIP and misinterprets Windows drive letters as URLs). Convert paths to
|
|
74
|
+
// forward-slash POSIX form so bsdtar receives them correctly.
|
|
75
|
+
function toPosix(p) { return p.replace(/\\/g, '/'); }
|
|
76
|
+
const [unzipCmd, unzipArgs] = process.platform === 'win32'
|
|
77
|
+
? ['C:\\Windows\\System32\\tar.exe', ['-xf', toPosix(targetFile), '-C', toPosix(extractDir)]]
|
|
78
|
+
: ['unzip', ['-o', '-q', targetFile, '-d', extractDir]];
|
|
79
|
+
try {
|
|
80
|
+
execFileSync(unzipCmd, unzipArgs, { stdio: 'pipe' });
|
|
81
|
+
console.log(`Extracted to: ${extractDir}`);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
if (error.code === 'ENOENT') {
|
|
84
|
+
console.error(
|
|
85
|
+
`Error: "${unzipCmd}" is not installed or not on PATH — ` +
|
|
86
|
+
(process.platform === 'win32'
|
|
87
|
+
? 'expected the tar.exe bundled with Windows 10 (1803+) / 11'
|
|
88
|
+
: 'install it (e.g. `apt install unzip`) and retry')
|
|
89
|
+
);
|
|
90
|
+
} else {
|
|
91
|
+
console.error(`Error: Failed to extract zip file — ${error.message}`);
|
|
92
|
+
}
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
console.log('[OK] CGCloudAddons static resource downloaded and extracted successfully\n');
|
|
97
|
+
return extractDir;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
module.exports = downloadStaticResource;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
function walkFiles(dir, extensions) {
|
|
5
|
+
const results = [];
|
|
6
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
7
|
+
const full = path.join(dir, entry.name);
|
|
8
|
+
if (entry.isDirectory()) results.push(...walkFiles(full, extensions));
|
|
9
|
+
else if (extensions.some(ext => entry.name.endsWith(ext))) results.push(full);
|
|
10
|
+
}
|
|
11
|
+
return results;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Step 2: Replace __SF_ORG_ID__ placeholder with actual org ID in all metadata files
|
|
16
|
+
*/
|
|
17
|
+
async function replaceOrgId(orgId, dataKitPath) {
|
|
18
|
+
console.log('\n=== Step 2: Replacing org ID placeholders ===');
|
|
19
|
+
console.log(`Target directory: ${dataKitPath}`);
|
|
20
|
+
console.log(`Org ID: ${orgId} (truncated to 15 chars: ${orgId.slice(0, 15)})`);
|
|
21
|
+
|
|
22
|
+
// Truncate org ID to 15 characters
|
|
23
|
+
const truncatedOrgId = orgId.slice(0, 15);
|
|
24
|
+
|
|
25
|
+
// Find all XML and JSON files
|
|
26
|
+
const files = walkFiles(dataKitPath, ['.xml', '.json']);
|
|
27
|
+
|
|
28
|
+
let replacementCount = 0;
|
|
29
|
+
|
|
30
|
+
files.forEach(file => {
|
|
31
|
+
try {
|
|
32
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
33
|
+
if (content.includes('__SF_ORG_ID__')) {
|
|
34
|
+
const newContent = content.replace(/__SF_ORG_ID__/g, truncatedOrgId);
|
|
35
|
+
fs.writeFileSync(file, newContent, 'utf8');
|
|
36
|
+
replacementCount++;
|
|
37
|
+
}
|
|
38
|
+
} catch (error) {
|
|
39
|
+
console.error(`Warning: Failed to process file ${file}: ${error.message}`);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
console.log(`[OK] Replaced org ID placeholder in ${replacementCount} file(s)\n`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = replaceOrgId;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const os = require('os');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const { exec, execDeployJson, execSfJson } = require('./utils');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Step 3: Deploy TPM Accruals Data Kit metadata to the org
|
|
8
|
+
* @param {string} orgAlias - The Salesforce org alias
|
|
9
|
+
* @param {string} dataKitPath - Path to the data kit
|
|
10
|
+
* @param {boolean} dryRun - If true, skip actual deployment
|
|
11
|
+
*/
|
|
12
|
+
async function deployMetadata(orgAlias, dataKitPath, dryRun = false) {
|
|
13
|
+
console.log('\n=== Step 3: Deploying TPM Accruals Data Kit ===');
|
|
14
|
+
console.log(`Source: ${dataKitPath}`);
|
|
15
|
+
console.log(`Target org: ${orgAlias}`);
|
|
16
|
+
|
|
17
|
+
if (dryRun) {
|
|
18
|
+
console.log('[DRY RUN] Skipping deployment - files prepared at:');
|
|
19
|
+
console.log(` ${dataKitPath}/force-app`);
|
|
20
|
+
console.log('[OK] Step 3 completed (dry run)\n');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Convert to MDAPI format first, then deploy via --metadata-dir.
|
|
25
|
+
// This bypasses SF CLI source-tracking ("NothingToDeploy" errors on non-scratch
|
|
26
|
+
// orgs where tracking state diverges from org reality).
|
|
27
|
+
const mdapiOut = path.join(os.tmpdir(), `tpm_accruals_mdapi_${Date.now()}`);
|
|
28
|
+
console.log('Converting source to MDAPI format...');
|
|
29
|
+
const convertResult = execSfJson(['project', 'convert', 'source', '--output-dir', mdapiOut, '--json'], { cwd: dataKitPath });
|
|
30
|
+
if (convertResult.status !== 0) {
|
|
31
|
+
throw new Error(`Source conversion failed: ${convertResult.message || JSON.stringify(convertResult)}`);
|
|
32
|
+
}
|
|
33
|
+
console.log(`Converted to: ${convertResult.result && convertResult.result.location || mdapiOut}`);
|
|
34
|
+
|
|
35
|
+
console.log('Deploying metadata...');
|
|
36
|
+
execDeployJson(['project', 'deploy', 'start', '--metadata-dir', mdapiOut, '--target-org', orgAlias]);
|
|
37
|
+
|
|
38
|
+
// Clean up temp dir
|
|
39
|
+
try { fs.rmSync(mdapiOut, { recursive: true }); } catch (cleanupErr) {
|
|
40
|
+
console.warn(`[WARN] Could not remove temp directory ${mdapiOut}: ${cleanupErr.message}`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
console.log('[OK] TPM Accruals Data Kit deployed successfully\n');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
module.exports = deployMetadata;
|