@salesforce/afv-skills 1.55.0 → 1.56.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/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-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-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-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/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/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-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-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-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-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,198 @@
|
|
|
1
|
+
const { execFileSync } = require('child_process');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const {
|
|
6
|
+
exec,
|
|
7
|
+
getOrgDetails,
|
|
8
|
+
getMaxCreatedDate,
|
|
9
|
+
getDeploymentLogForComponents,
|
|
10
|
+
getDeployedComponents,
|
|
11
|
+
waitForDeploymentCompletion,
|
|
12
|
+
} = require('./utils');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Build component specs (id + names to match in DataKitDeploymentLog) for each
|
|
16
|
+
* component in a deployment payload.
|
|
17
|
+
*/
|
|
18
|
+
function buildComponentSpecs(payload) {
|
|
19
|
+
const specs = [];
|
|
20
|
+
|
|
21
|
+
const components =
|
|
22
|
+
payload && payload.inputs && payload.inputs[0] && payload.inputs[0].dataKitComponentsInput
|
|
23
|
+
? payload.inputs[0].dataKitComponentsInput
|
|
24
|
+
: [];
|
|
25
|
+
|
|
26
|
+
components.forEach(component => {
|
|
27
|
+
if (component.dloConfig) {
|
|
28
|
+
specs.push({
|
|
29
|
+
id: component.dloConfig.apiName,
|
|
30
|
+
type: 'DataLakeObject',
|
|
31
|
+
names: [component.dloConfig.apiName, component.dloConfig.dataSourceObjectDevName].filter(Boolean),
|
|
32
|
+
});
|
|
33
|
+
} else if (component.dataTransformConfig) {
|
|
34
|
+
specs.push({
|
|
35
|
+
id: component.dataTransformConfig.apiName || component.dataTransformConfig.dataTransformDevName,
|
|
36
|
+
type: 'DataTransform',
|
|
37
|
+
names: [
|
|
38
|
+
component.dataTransformConfig.apiName,
|
|
39
|
+
component.dataTransformConfig.dataTransformDevName,
|
|
40
|
+
].filter(Boolean),
|
|
41
|
+
});
|
|
42
|
+
} else if (component.bundleConfig) {
|
|
43
|
+
specs.push({
|
|
44
|
+
id: component.bundleConfig.bundleName,
|
|
45
|
+
type: 'DataStreamBundle',
|
|
46
|
+
names: [component.bundleConfig.bundleName].filter(Boolean),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
return specs;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Step 4: Deploy Liability Accruals Engine data kit
|
|
56
|
+
* @param {string} orgAlias - The Salesforce org alias
|
|
57
|
+
* @param {string} scriptsDir - Path to the scripts directory
|
|
58
|
+
* @param {string} orgId - The Salesforce org ID
|
|
59
|
+
* @param {string} namespace - Org namespace prefix (e.g. "cgcloud_dev__"), or '' for unmanaged orgs
|
|
60
|
+
* @param {boolean} dryRun - If true, skip actual deployment
|
|
61
|
+
*/
|
|
62
|
+
async function deployEngine(orgAlias, scriptsDir, orgId, namespace = '', dryRun = false) {
|
|
63
|
+
console.log('\n=== Step 4: Deploying Liability Accruals Engine ===');
|
|
64
|
+
|
|
65
|
+
const dataKitName = 'LiabilityAccrualsEngine';
|
|
66
|
+
const payloadPath = path.join(scriptsDir, 'engine-deployment-payload.json');
|
|
67
|
+
|
|
68
|
+
console.log(`Payload: ${payloadPath}`);
|
|
69
|
+
|
|
70
|
+
if (namespace) {
|
|
71
|
+
console.log(`Org namespace: ${namespace}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const payload = JSON.parse(fs.readFileSync(payloadPath, 'utf8'));
|
|
75
|
+
const originalPayload = JSON.parse(JSON.stringify(payload));
|
|
76
|
+
const allComponentSpecs = buildComponentSpecs(payload);
|
|
77
|
+
const deploymentLog = getDeploymentLogForComponents(orgAlias, allComponentSpecs);
|
|
78
|
+
const deployedIds = getDeployedComponents(deploymentLog, allComponentSpecs, namespace);
|
|
79
|
+
|
|
80
|
+
if (deployedIds.size > 0) {
|
|
81
|
+
console.log(`Found ${deployedIds.size} already deployed components:`);
|
|
82
|
+
deployedIds.forEach(comp => console.log(` - ${comp}`));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const components = payload.inputs[0].dataKitComponentsInput;
|
|
86
|
+
const componentsToSkip = new Set();
|
|
87
|
+
|
|
88
|
+
components.forEach((component, index) => {
|
|
89
|
+
let identifier = '';
|
|
90
|
+
|
|
91
|
+
if (component.dloConfig) {
|
|
92
|
+
identifier = component.dloConfig.apiName;
|
|
93
|
+
} else if (component.dataTransformConfig) {
|
|
94
|
+
identifier =
|
|
95
|
+
component.dataTransformConfig.apiName || component.dataTransformConfig.dataTransformDevName;
|
|
96
|
+
} else if (component.bundleConfig) {
|
|
97
|
+
identifier = component.bundleConfig.bundleName;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (identifier && deployedIds.has(identifier)) {
|
|
101
|
+
componentsToSkip.add(index);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
if (componentsToSkip.size > 0) {
|
|
106
|
+
console.log(`Skipping ${componentsToSkip.size} already deployed components`);
|
|
107
|
+
payload.inputs[0].dataKitComponentsInput = components.filter(
|
|
108
|
+
(_, index) => !componentsToSkip.has(index),
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const componentCount = payload.inputs[0].dataKitComponentsInput.length;
|
|
113
|
+
|
|
114
|
+
if (componentCount === 0) {
|
|
115
|
+
console.log(`[OK] All components already deployed, skipping ${dataKitName}\n`);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
console.log(`${dryRun ? 'Would deploy' : 'Deploying'} ${componentCount} components...`);
|
|
120
|
+
|
|
121
|
+
const componentSpecs = buildComponentSpecs(payload);
|
|
122
|
+
const payloadString = JSON.stringify(payload);
|
|
123
|
+
const updatedPayloadString = payloadString.replace(/<SF_ORG_ID>/g, orgId.slice(0, 15));
|
|
124
|
+
const updatedPayload = JSON.parse(updatedPayloadString);
|
|
125
|
+
|
|
126
|
+
if (dryRun) {
|
|
127
|
+
console.log('[DRY RUN] Skipping deployment - components that would be deployed:');
|
|
128
|
+
componentSpecs.forEach(spec => console.log(` - [${spec.type}] ${spec.id}`));
|
|
129
|
+
console.log(`[DRY RUN] Payload file: ${payloadPath}`);
|
|
130
|
+
console.log('[OK] Step 4 completed (dry run)\n');
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const backupPath = payloadPath + '.backup';
|
|
135
|
+
fs.writeFileSync(backupPath, JSON.stringify(originalPayload, null, 2));
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
const orgDetails = getOrgDetails(orgAlias);
|
|
139
|
+
const url = `${orgDetails.instanceUrl}/services/data/v62.0/actions/custom/flow/sfdatakit__DeployDataKitComponents`;
|
|
140
|
+
|
|
141
|
+
// Capture the Salesforce server timestamp before triggering deploy so the
|
|
142
|
+
// poller uses WHERE CreatedDate >= deploymentStartTime (immune to local clock-skew).
|
|
143
|
+
let deploymentStartTime = '';
|
|
144
|
+
try {
|
|
145
|
+
deploymentStartTime = getMaxCreatedDate(orgAlias);
|
|
146
|
+
} catch (_) {
|
|
147
|
+
// If server-time query fails, fall back to no filter — better than crashing
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const headerFile = path.join(os.tmpdir(), `sf-auth-${process.pid}.txt`);
|
|
151
|
+
const bodyFile = path.join(os.tmpdir(), `sf-body-${process.pid}.json`);
|
|
152
|
+
let response;
|
|
153
|
+
try {
|
|
154
|
+
fs.writeFileSync(
|
|
155
|
+
headerFile,
|
|
156
|
+
`Authorization: Bearer ${orgDetails.accessToken}\n`,
|
|
157
|
+
{ mode: 0o600 },
|
|
158
|
+
);
|
|
159
|
+
fs.writeFileSync(bodyFile, JSON.stringify(updatedPayload), { mode: 0o600 });
|
|
160
|
+
response = execFileSync(
|
|
161
|
+
'curl',
|
|
162
|
+
[
|
|
163
|
+
'-s',
|
|
164
|
+
'-X',
|
|
165
|
+
'POST',
|
|
166
|
+
url,
|
|
167
|
+
'--header',
|
|
168
|
+
`@${headerFile}`,
|
|
169
|
+
'-H',
|
|
170
|
+
'Content-Type: application/json',
|
|
171
|
+
'--data',
|
|
172
|
+
`@${bodyFile}`,
|
|
173
|
+
],
|
|
174
|
+
{ encoding: 'utf8' },
|
|
175
|
+
);
|
|
176
|
+
} finally {
|
|
177
|
+
try { fs.unlinkSync(headerFile); } catch (e) { console.warn(`Warning: failed to delete auth header file ${headerFile}: ${e.message}`); }
|
|
178
|
+
try { fs.unlinkSync(bodyFile); } catch (e) { console.warn(`Warning: failed to delete body file ${bodyFile}: ${e.message}`); }
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const result = JSON.parse(response);
|
|
182
|
+
console.log('Deployment initiated');
|
|
183
|
+
|
|
184
|
+
if (result.isSuccess === false || result.errors) {
|
|
185
|
+
console.error('Deployment API returned errors:', result);
|
|
186
|
+
throw new Error('Deployment failed');
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
await waitForDeploymentCompletion(orgAlias, componentSpecs, deploymentStartTime, namespace);
|
|
190
|
+
} finally {
|
|
191
|
+
fs.writeFileSync(payloadPath, JSON.stringify(originalPayload, null, 2));
|
|
192
|
+
try {
|
|
193
|
+
fs.unlinkSync(backupPath);
|
|
194
|
+
} catch (_) {}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
module.exports = deployEngine;
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
const { execFileSync } = require('child_process');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const {
|
|
6
|
+
exec,
|
|
7
|
+
getOrgDetails,
|
|
8
|
+
getMaxCreatedDate,
|
|
9
|
+
getBundleStreamMap,
|
|
10
|
+
getDeploymentLogForComponents,
|
|
11
|
+
getDeployedComponents,
|
|
12
|
+
waitForDeploymentCompletion,
|
|
13
|
+
} = require('./utils');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Build a list of component specs from a deployment payload.
|
|
17
|
+
* Each spec carries an id (used for logging) and an array of names that, if
|
|
18
|
+
* any are recorded as Successful in DataKitDeploymentLog, indicate the
|
|
19
|
+
* component was deployed.
|
|
20
|
+
*
|
|
21
|
+
* For DataStreamBundle components we also include the developer names of the
|
|
22
|
+
* dataStreamTemplates contained in the bundle, since DataKitDeploymentLog
|
|
23
|
+
* tends to record the underlying streams rather than the bundle name itself.
|
|
24
|
+
*
|
|
25
|
+
* @param {object} payload - The DeployDataKitComponents payload
|
|
26
|
+
* @param {Map<string, string[]>} bundleStreamMap - bundleName -> [streamDevNames]
|
|
27
|
+
* @returns {Array<{id: string, type: string, names: string[]}>}
|
|
28
|
+
*/
|
|
29
|
+
function buildComponentSpecs(payload, bundleStreamMap) {
|
|
30
|
+
const specs = [];
|
|
31
|
+
|
|
32
|
+
const components =
|
|
33
|
+
payload &&
|
|
34
|
+
payload.inputs &&
|
|
35
|
+
payload.inputs[0] &&
|
|
36
|
+
payload.inputs[0].dataKitComponentsInput
|
|
37
|
+
? payload.inputs[0].dataKitComponentsInput
|
|
38
|
+
: [];
|
|
39
|
+
|
|
40
|
+
components.forEach(component => {
|
|
41
|
+
if (component.dloConfig) {
|
|
42
|
+
specs.push({
|
|
43
|
+
id: component.dloConfig.apiName,
|
|
44
|
+
type: 'DataLakeObject',
|
|
45
|
+
names: [component.dloConfig.apiName, component.dloConfig.dataSourceObjectDevName].filter(Boolean),
|
|
46
|
+
});
|
|
47
|
+
} else if (component.dataTransformConfig) {
|
|
48
|
+
specs.push({
|
|
49
|
+
id: component.dataTransformConfig.apiName || component.dataTransformConfig.dataTransformDevName,
|
|
50
|
+
type: 'DataTransform',
|
|
51
|
+
names: [
|
|
52
|
+
component.dataTransformConfig.apiName,
|
|
53
|
+
component.dataTransformConfig.dataTransformDevName,
|
|
54
|
+
].filter(Boolean),
|
|
55
|
+
});
|
|
56
|
+
} else if (component.bundleConfig) {
|
|
57
|
+
const bundleName = component.bundleConfig.bundleName;
|
|
58
|
+
const childStreams = bundleStreamMap.get(bundleName) || [];
|
|
59
|
+
// Bundles may not appear by their bundle name in the deployment log.
|
|
60
|
+
// Track them by bundle name AND by their child data stream developer names.
|
|
61
|
+
specs.push({
|
|
62
|
+
id: bundleName,
|
|
63
|
+
type: 'DataStreamBundle',
|
|
64
|
+
names: [bundleName, ...childStreams],
|
|
65
|
+
});
|
|
66
|
+
} else if (component.dataActionTargetConfig) {
|
|
67
|
+
specs.push({
|
|
68
|
+
id: component.dataActionTargetConfig.name,
|
|
69
|
+
type: 'DataActionTarget',
|
|
70
|
+
names: [component.dataActionTargetConfig.name].filter(Boolean),
|
|
71
|
+
});
|
|
72
|
+
} else if (component.dataActionConfig) {
|
|
73
|
+
specs.push({
|
|
74
|
+
id: component.dataActionConfig.name,
|
|
75
|
+
type: 'DataAction',
|
|
76
|
+
names: [component.dataActionConfig.name].filter(Boolean),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
return specs;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Step 5: Deploy TPM Accruals data kit
|
|
86
|
+
* @param {string} orgAlias - The Salesforce org alias
|
|
87
|
+
* @param {string} scriptsDir - Path to the scripts directory
|
|
88
|
+
* @param {string} dataKitPath - Path to the TPM Accruals Data Kit (for bundle->stream mapping)
|
|
89
|
+
* @param {string} orgId - The Salesforce org ID
|
|
90
|
+
* @param {string} namespace - Org namespace prefix (e.g. "cgcloud_dev__"), or '' for unmanaged orgs
|
|
91
|
+
* @param {boolean} dryRun - If true, skip actual deployment
|
|
92
|
+
*/
|
|
93
|
+
async function deployTPMAccruals(orgAlias, scriptsDir, dataKitPath, orgId, namespace = '', dryRun = false) {
|
|
94
|
+
console.log('\n=== Step 5: Deploying TPM Accruals ===');
|
|
95
|
+
|
|
96
|
+
const dataKitName = 'TPM_Accruals';
|
|
97
|
+
const payloadPath = path.join(scriptsDir, 'tpm-accruals-deployment-payload.json');
|
|
98
|
+
|
|
99
|
+
console.log(`Payload: ${payloadPath}`);
|
|
100
|
+
if (namespace) {
|
|
101
|
+
console.log(`Org namespace: ${namespace}`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Read payload
|
|
105
|
+
const payload = JSON.parse(fs.readFileSync(payloadPath, 'utf8'));
|
|
106
|
+
const originalPayload = JSON.parse(JSON.stringify(payload));
|
|
107
|
+
|
|
108
|
+
// Build bundle -> [stream developer names] map from the data kit's metadata.
|
|
109
|
+
// This lets us recognize a bundle as deployed when its underlying streams
|
|
110
|
+
// appear in the deployment log even if the bundle name itself does not.
|
|
111
|
+
const bundleStreamMap = getBundleStreamMap(dataKitPath);
|
|
112
|
+
|
|
113
|
+
// Build component specs (one per declared component) from the original payload
|
|
114
|
+
const allComponentSpecs = buildComponentSpecs(payload, bundleStreamMap);
|
|
115
|
+
|
|
116
|
+
// Check existing deployments for these specific components
|
|
117
|
+
const deploymentLog = getDeploymentLogForComponents(orgAlias, allComponentSpecs);
|
|
118
|
+
const deployedIds = getDeployedComponents(deploymentLog, allComponentSpecs, namespace);
|
|
119
|
+
|
|
120
|
+
if (deployedIds.size > 0) {
|
|
121
|
+
console.log(`Found ${deployedIds.size} already deployed components:`);
|
|
122
|
+
deployedIds.forEach(comp => console.log(` - ${comp}`));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Filter out already deployed components from the payload
|
|
126
|
+
const components = payload.inputs[0].dataKitComponentsInput;
|
|
127
|
+
const componentsToSkip = new Set();
|
|
128
|
+
|
|
129
|
+
components.forEach((component, index) => {
|
|
130
|
+
let identifier = '';
|
|
131
|
+
if (component.dloConfig) {
|
|
132
|
+
identifier = component.dloConfig.apiName;
|
|
133
|
+
} else if (component.dataTransformConfig) {
|
|
134
|
+
identifier = component.dataTransformConfig.apiName || component.dataTransformConfig.dataTransformDevName;
|
|
135
|
+
} else if (component.bundleConfig) {
|
|
136
|
+
identifier = component.bundleConfig.bundleName;
|
|
137
|
+
} else if (component.dataActionTargetConfig) {
|
|
138
|
+
identifier = component.dataActionTargetConfig.name;
|
|
139
|
+
} else if (component.dataActionConfig) {
|
|
140
|
+
identifier = component.dataActionConfig.name;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (identifier && deployedIds.has(identifier)) {
|
|
144
|
+
componentsToSkip.add(index);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
if (componentsToSkip.size > 0) {
|
|
149
|
+
console.log(`Skipping ${componentsToSkip.size} already deployed components`);
|
|
150
|
+
payload.inputs[0].dataKitComponentsInput = components.filter((_, index) =>
|
|
151
|
+
!componentsToSkip.has(index)
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const componentCount = payload.inputs[0].dataKitComponentsInput.length;
|
|
156
|
+
|
|
157
|
+
if (componentCount === 0) {
|
|
158
|
+
console.log(`[OK] All components already deployed, skipping ${dataKitName}\n`);
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
console.log(`${dryRun ? 'Would deploy' : 'Deploying'} ${componentCount} components...`);
|
|
163
|
+
|
|
164
|
+
// Build component specs for the components actually being deployed
|
|
165
|
+
const componentSpecs = buildComponentSpecs(payload, bundleStreamMap);
|
|
166
|
+
|
|
167
|
+
// Replace org ID placeholder
|
|
168
|
+
const payloadString = JSON.stringify(payload);
|
|
169
|
+
const updatedPayloadString = payloadString.replace(/<SF_ORG_ID>/g, orgId.slice(0, 15));
|
|
170
|
+
const updatedPayload = JSON.parse(updatedPayloadString);
|
|
171
|
+
|
|
172
|
+
if (dryRun) {
|
|
173
|
+
console.log('[DRY RUN] Skipping deployment - components that would be deployed:');
|
|
174
|
+
componentSpecs.forEach(spec => {
|
|
175
|
+
const extras = spec.names.length > 1 ? ` (also tracked via: ${spec.names.slice(1).join(', ')})` : '';
|
|
176
|
+
console.log(` - [${spec.type}] ${spec.id}${extras}`);
|
|
177
|
+
});
|
|
178
|
+
console.log(`[DRY RUN] Payload file: ${payloadPath}`);
|
|
179
|
+
console.log('[OK] Step 5 completed (dry run)\n');
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Save backup
|
|
184
|
+
const backupPath = payloadPath + '.backup';
|
|
185
|
+
fs.writeFileSync(backupPath, JSON.stringify(originalPayload, null, 2));
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
const orgDetails = getOrgDetails(orgAlias);
|
|
189
|
+
const url = `${orgDetails.instanceUrl}/services/data/v62.0/actions/custom/flow/sfdatakit__DeployDataKitComponents`;
|
|
190
|
+
|
|
191
|
+
// Capture the Salesforce server timestamp before triggering deploy so the
|
|
192
|
+
// poller uses WHERE CreatedDate >= deploymentStartTime (immune to local clock-skew).
|
|
193
|
+
let deploymentStartTime = '';
|
|
194
|
+
try {
|
|
195
|
+
deploymentStartTime = getMaxCreatedDate(orgAlias);
|
|
196
|
+
} catch (_) {
|
|
197
|
+
// If server-time query fails, fall back to no filter — better than crashing
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const headerFile = path.join(os.tmpdir(), `sf-auth-${process.pid}.txt`);
|
|
201
|
+
const bodyFile = path.join(os.tmpdir(), `sf-body-${process.pid}.json`);
|
|
202
|
+
let response;
|
|
203
|
+
try {
|
|
204
|
+
fs.writeFileSync(headerFile, `Authorization: Bearer ${orgDetails.accessToken}\n`, { mode: 0o600 });
|
|
205
|
+
fs.writeFileSync(bodyFile, JSON.stringify(updatedPayload), { mode: 0o600 });
|
|
206
|
+
response = execFileSync(
|
|
207
|
+
'curl',
|
|
208
|
+
['-s', '-X', 'POST', url, '--header', `@${headerFile}`, '-H', 'Content-Type: application/json', '--data', `@${bodyFile}`],
|
|
209
|
+
{ encoding: 'utf8' },
|
|
210
|
+
);
|
|
211
|
+
} finally {
|
|
212
|
+
try { fs.unlinkSync(headerFile); } catch (e) { console.warn(`Warning: failed to delete auth header file ${headerFile}: ${e.message}`); }
|
|
213
|
+
try { fs.unlinkSync(bodyFile); } catch (e) { console.warn(`Warning: failed to delete body file ${bodyFile}: ${e.message}`); }
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const result = JSON.parse(response);
|
|
217
|
+
console.log('Deployment initiated');
|
|
218
|
+
|
|
219
|
+
if (result.isSuccess === false || result.errors) {
|
|
220
|
+
console.error('Deployment API returned errors:', result);
|
|
221
|
+
throw new Error('Deployment failed');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
await waitForDeploymentCompletion(orgAlias, componentSpecs, deploymentStartTime, namespace);
|
|
225
|
+
} finally {
|
|
226
|
+
fs.writeFileSync(payloadPath, JSON.stringify(originalPayload, null, 2));
|
|
227
|
+
fs.unlinkSync(backupPath);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
module.exports = deployTPMAccruals;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const readline = require('readline');
|
|
2
|
+
const { execSfJson } = require('./utils');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Step 6: Manual Data Space creation with DLO configuration
|
|
6
|
+
* @param {string} orgAlias - The Salesforce org alias
|
|
7
|
+
* @param {string} salesOrg - The sales org value (e.g., "0001")
|
|
8
|
+
* @param {string} dataSpaceName - The data space name (e.g., "DataSpace_0001")
|
|
9
|
+
* @param {string} dataSpacePrefix - The data space prefix (e.g., "DS1")
|
|
10
|
+
* @param {boolean} dryRun - If true, skip user prompt
|
|
11
|
+
*/
|
|
12
|
+
async function createDataSpace(orgAlias, salesOrg, dataSpaceName, dataSpacePrefix, dryRun = false) {
|
|
13
|
+
console.log('\n=== Step 6: Create Data Space (Manual Step) ===');
|
|
14
|
+
|
|
15
|
+
console.log('\nData Space configuration:');
|
|
16
|
+
console.log(` - Name: ${dataSpaceName}`);
|
|
17
|
+
console.log(` - Prefix: ${dataSpacePrefix}`);
|
|
18
|
+
console.log(` - DLO: accrualoutput_decorated__dll`);
|
|
19
|
+
console.log(` - Filter: SalesOrg equals "${salesOrg}"`);
|
|
20
|
+
|
|
21
|
+
if (dryRun) {
|
|
22
|
+
console.log('\n[DRY RUN] Skipping manual step prompt');
|
|
23
|
+
console.log('[OK] Step 6 completed (dry run)\n');
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
console.log('\nPlease complete the following manual steps in your Salesforce org:');
|
|
28
|
+
console.log('\n1. Navigate to the Data Spaces tab in your org');
|
|
29
|
+
console.log('2. Create a new Data Space with the details shown above');
|
|
30
|
+
console.log('3. Go into the newly created Data Space');
|
|
31
|
+
console.log('4. Add the DLO: accrualoutput_decorated__dll');
|
|
32
|
+
console.log('5. Apply the filter shown above');
|
|
33
|
+
|
|
34
|
+
console.log('\n');
|
|
35
|
+
|
|
36
|
+
// Wait for user confirmation
|
|
37
|
+
await waitForUserConfirmation();
|
|
38
|
+
|
|
39
|
+
// In headless mode, verify the Data Space actually exists before continuing.
|
|
40
|
+
// DataSpace is a queryable SOQL object — query it to confirm creation.
|
|
41
|
+
if (!process.stdin.isTTY) {
|
|
42
|
+
const verifyResult = execSfJson([
|
|
43
|
+
'data', 'query', '--target-org', orgAlias, '--json',
|
|
44
|
+
'--query', `SELECT Id, Status FROM DataSpace WHERE DataSpaceApiName = '${dataSpaceName}' LIMIT 1`
|
|
45
|
+
]);
|
|
46
|
+
const records = (verifyResult.result && verifyResult.result.records) || [];
|
|
47
|
+
if (records.length === 0) {
|
|
48
|
+
throw new Error(
|
|
49
|
+
`Data Space '${dataSpaceName}' not found in org. ` +
|
|
50
|
+
`Create it manually (Data Cloud app → Data Spaces → New, prefix '${dataSpacePrefix}', ` +
|
|
51
|
+
`add DLO accrualoutput_decorated__dll with SalesOrg = '${salesOrg}') before re-running.`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
console.log(`[OK] Data Space '${dataSpaceName}' verified (Status: ${records[0].Status}).\n`);
|
|
55
|
+
} else {
|
|
56
|
+
console.log('[OK] Data Space creation confirmed. Proceeding to next step...\n');
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Wait for user to press Enter.
|
|
62
|
+
* Auto-confirms immediately when stdin is not a TTY (piped / headless run).
|
|
63
|
+
*/
|
|
64
|
+
function waitForUserConfirmation() {
|
|
65
|
+
if (!process.stdin.isTTY) {
|
|
66
|
+
console.log('[Auto-confirmed: running non-interactively]');
|
|
67
|
+
return Promise.resolve();
|
|
68
|
+
}
|
|
69
|
+
return new Promise((resolve) => {
|
|
70
|
+
const rl = readline.createInterface({
|
|
71
|
+
input: process.stdin,
|
|
72
|
+
output: process.stdout
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
rl.question('Press Enter when you have completed these steps...', () => {
|
|
76
|
+
rl.close();
|
|
77
|
+
resolve();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
module.exports = createDataSpace;
|