@adobe/aio-commerce-lib-app 2.0.0-beta-20260820174436 → 2.0.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/CHANGELOG.md +31 -5
- package/dist/cjs/actions/app-config/index.cjs +3 -3
- package/dist/cjs/actions/app-config/index.d.cts +3 -4
- package/dist/cjs/actions/association/index.d.cts +2 -3
- package/dist/cjs/actions/config/index.d.cts +2 -3
- package/dist/cjs/actions/installation/index.cjs +14 -7
- package/dist/cjs/actions/installation/index.d.cts +5 -5
- package/dist/cjs/actions/scope-tree/index.d.cts +2 -3
- package/dist/cjs/{app-Cf3EmtUh.d.cts → app-DwSqUkJA.d.cts} +122 -16
- package/dist/cjs/commands/index.cjs +91 -51
- package/dist/cjs/commands/templates/admin-ui/web-src/.babelrc +14 -0
- package/dist/cjs/commands/templates/business-configuration/config.js.template +7 -1
- package/dist/cjs/{common-B70f39vI.cjs → common-VSsQEHDv.cjs} +15 -2
- package/dist/cjs/config/index.browser.d.cts +1 -1
- package/dist/cjs/config/index.node.cjs +4 -3
- package/dist/cjs/config/index.node.d.cts +104 -50
- package/dist/{es/define-DSU8Kgu0.d.mts → cjs/define-Cc3AaVmY.d.cts} +1 -1
- package/dist/{es/index-COLnI6Ok.d.mts → cjs/index-C7dqTDHu.d.cts} +25 -3
- package/dist/cjs/index.d.cts +10 -10
- package/dist/cjs/{index.node-CXeIG8SS.cjs → index.node-vcOo1rt0.cjs} +1 -1
- package/dist/cjs/installation-D72LoQ_1.d.cts +39 -0
- package/dist/cjs/management/index.cjs +1 -1
- package/dist/cjs/management/index.d.cts +1 -1
- package/dist/cjs/{management-BhMdRr8i.cjs → management-Bki3hlxL.cjs} +207 -27
- package/dist/cjs/{openapi-DVJUTOXY.cjs → openapi-CAXgKam0.cjs} +317 -390
- package/dist/cjs/{validate-Dff0nrqM.cjs → validate-CwWYtRsS.cjs} +33 -2
- package/dist/cjs/{webhooks-E1KDx3Yu.cjs → webhooks-Bcq2Qy7q.cjs} +69 -8
- package/dist/es/actions/app-config/index.d.mts +3 -4
- package/dist/es/actions/app-config/index.mjs +3 -3
- package/dist/es/actions/association/index.d.mts +2 -3
- package/dist/es/actions/config/index.d.mts +2 -3
- package/dist/es/actions/installation/index.d.mts +5 -5
- package/dist/es/actions/installation/index.mjs +14 -7
- package/dist/es/actions/scope-tree/index.d.mts +2 -3
- package/dist/es/{app-Cf3EmtUh.d.mts → app-DwSqUkJA.d.mts} +122 -16
- package/dist/es/commands/index.mjs +92 -52
- package/dist/es/commands/templates/admin-ui/web-src/.babelrc +14 -0
- package/dist/es/commands/templates/business-configuration/config.js.template +7 -1
- package/dist/es/{common-BVG9tiX0.mjs → common-dy6NrZt8.mjs} +10 -3
- package/dist/es/config/index.browser.d.mts +1 -1
- package/dist/es/config/index.node.d.mts +104 -50
- package/dist/es/config/index.node.mjs +4 -4
- package/dist/{cjs/define-B-_oKmCe.d.cts → es/define-Bq1zw9Lr.d.mts} +1 -1
- package/dist/{cjs/index-CkwCGvut.d.cts → es/index-BryddQId.d.mts} +25 -3
- package/dist/es/index.d.mts +10 -10
- package/dist/es/{index.node-DRTF5Hue.mjs → index.node-CW46zuxW.mjs} +1 -1
- package/dist/es/installation-DqVDJ1ur.d.mts +39 -0
- package/dist/es/management/index.d.mts +1 -1
- package/dist/es/management/index.mjs +1 -1
- package/dist/es/{management-BTWQdJNO.mjs → management-DgwAhaaJ.mjs} +207 -27
- package/dist/es/{openapi-D18LT0Wp.mjs → openapi-BnR9OUac.mjs} +317 -390
- package/dist/es/{validate-8AXMGEwr.mjs → validate-NzW1FQwL.mjs} +29 -4
- package/dist/es/{webhooks-BQ8kSN2Z.mjs → webhooks-CHZ1SXxw.mjs} +64 -9
- package/package.json +19 -19
|
@@ -16,7 +16,7 @@ const require_rolldown_runtime = require('./rolldown-runtime-CDQd2xEI.cjs');
|
|
|
16
16
|
const require_utils = require('./utils-CHfNw_aP.cjs');
|
|
17
17
|
const require_error = require('./error-D-N0PKSl.cjs');
|
|
18
18
|
const require_environment = require('./environment-B6533pAY.cjs');
|
|
19
|
-
const require_webhooks = require('./webhooks-
|
|
19
|
+
const require_webhooks = require('./webhooks-Bcq2Qy7q.cjs');
|
|
20
20
|
const require_logging = require('./logging-Br3xfBNe.cjs');
|
|
21
21
|
let _adobe_aio_commerce_lib_api = require("@adobe/aio-commerce-lib-api");
|
|
22
22
|
let _adobe_aio_commerce_lib_config = require("@adobe/aio-commerce-lib-config");
|
|
@@ -25,11 +25,11 @@ let safe_stable_stringify = require("safe-stable-stringify");
|
|
|
25
25
|
safe_stable_stringify = require_rolldown_runtime.__toESM(safe_stable_stringify, 1);
|
|
26
26
|
let valibot = require("valibot");
|
|
27
27
|
valibot = require_rolldown_runtime.__toESM(valibot, 1);
|
|
28
|
+
let _adobe_aio_commerce_lib_admin_ui_api = require("@adobe/aio-commerce-lib-admin-ui/api");
|
|
28
29
|
let ky = require("ky");
|
|
29
30
|
let _adobe_aio_commerce_lib_api_utils = require("@adobe/aio-commerce-lib-api/utils");
|
|
30
31
|
let camelcase = require("camelcase");
|
|
31
32
|
camelcase = require_rolldown_runtime.__toESM(camelcase, 1);
|
|
32
|
-
let _adobe_aio_commerce_lib_admin_ui_api = require("@adobe/aio-commerce-lib-admin-ui/api");
|
|
33
33
|
let _adobe_aio_commerce_lib_events_commerce = require("@adobe/aio-commerce-lib-events/commerce");
|
|
34
34
|
let _adobe_aio_commerce_lib_events_io_events = require("@adobe/aio-commerce-lib-events/io-events");
|
|
35
35
|
let _adobe_aio_commerce_lib_webhooks_api = require("@adobe/aio-commerce-lib-webhooks/api");
|
|
@@ -515,6 +515,18 @@ function resolveCustomScriptHandler(scriptModule, handler) {
|
|
|
515
515
|
return null;
|
|
516
516
|
}
|
|
517
517
|
/**
|
|
518
|
+
* Resolves a script module from the customScripts context, throwing when it's absent.
|
|
519
|
+
*
|
|
520
|
+
* @param customScripts - The customScripts context containing the loaded modules.
|
|
521
|
+
* @param script - The script path to resolve the module for.
|
|
522
|
+
* @throws If the script is not present in the context.
|
|
523
|
+
*/
|
|
524
|
+
function getScriptModuleOrThrow(customScripts, script) {
|
|
525
|
+
const scriptModule = getScriptModule(customScripts, script);
|
|
526
|
+
if (!scriptModule) throw new Error(`Script ${script} not found in customScripts context. Make sure the script is defined in the configuration and the action was generated with custom scripts support.`);
|
|
527
|
+
return scriptModule;
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
518
530
|
* Creates a leaf step for executing a single custom installation script.
|
|
519
531
|
*/
|
|
520
532
|
function createCustomScriptStep(scriptConfig) {
|
|
@@ -525,9 +537,7 @@ function createCustomScriptStep(scriptConfig) {
|
|
|
525
537
|
const customScripts = context.customScripts || {};
|
|
526
538
|
logger.info(`Executing custom installation script: ${name}`);
|
|
527
539
|
logger.debug(`Script path: ${script}`);
|
|
528
|
-
const
|
|
529
|
-
if (!scriptModule) throw new Error(`Script ${script} not found in customScripts context. Make sure the script is defined in the configuration and the action was generated with custom scripts support.`);
|
|
530
|
-
const scriptResult = await resolveCustomScriptHandler(scriptModule, "install")(config, context);
|
|
540
|
+
const scriptResult = await resolveCustomScriptHandler(getScriptModuleOrThrow(customScripts, script), "install")(config, context);
|
|
531
541
|
logger.info(`Successfully executed script: ${name}`);
|
|
532
542
|
return {
|
|
533
543
|
data: scriptResult,
|
|
@@ -569,8 +579,134 @@ function createCustomScriptSteps(config) {
|
|
|
569
579
|
return steps.map((scriptConfig) => createCustomScriptStep(scriptConfig));
|
|
570
580
|
}
|
|
571
581
|
|
|
582
|
+
//#endregion
|
|
583
|
+
//#region source/management/domains/custom-installation/apply.ts
|
|
584
|
+
/** Runs a newly-added step's `install` handler and returns its persisted identity. */
|
|
585
|
+
async function runAddedStep(step, targetConfig, context) {
|
|
586
|
+
const { logger } = context;
|
|
587
|
+
const scriptModule = getScriptModuleOrThrow(context.customScripts ?? {}, step.script);
|
|
588
|
+
logger.info(`Executing custom installation script: ${step.name}`);
|
|
589
|
+
await resolveCustomScriptHandler(scriptModule, "install")(targetConfig, context);
|
|
590
|
+
logger.info(`Successfully executed script: ${step.name}`);
|
|
591
|
+
return {
|
|
592
|
+
name: step.name,
|
|
593
|
+
script: step.script
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Applies the plan: runs `install` for first-time steps, warns about retained steps that point to
|
|
598
|
+
* a different script (without re-running them), and ignores steps no longer in the config. Returns
|
|
599
|
+
* the baseline history with the newly-added steps appended.
|
|
600
|
+
*/
|
|
601
|
+
async function applyCustomInstallationSteps(plan, context) {
|
|
602
|
+
const { baselineExecutedSteps, targetConfig, operations } = plan;
|
|
603
|
+
if (!targetConfig) return { snapshotData: { executedSteps: baselineExecutedSteps } };
|
|
604
|
+
const targetSteps = require_webhooks.hasCustomInstallationSteps(targetConfig) ? targetConfig.installation.customInstallationSteps : [];
|
|
605
|
+
const addedNames = new Set(operations.filter((op) => op.kind === "add").map((op) => op.after.name));
|
|
606
|
+
for (const targetStep of targetSteps) {
|
|
607
|
+
if (addedNames.has(targetStep.name)) continue;
|
|
608
|
+
const baselineStep = baselineExecutedSteps.find((step) => step.name === targetStep.name);
|
|
609
|
+
if (baselineStep && baselineStep.script !== targetStep.script) context.logger.warn(`Custom installation step "${targetStep.name}" now points to a different script ("${targetStep.script}" instead of "${baselineStep.script}"). This does not affect append-only behavior: its install already ran and will not run again.`);
|
|
610
|
+
}
|
|
611
|
+
const addedSteps = targetSteps.filter((step) => addedNames.has(step.name));
|
|
612
|
+
const addedIdentities = [];
|
|
613
|
+
for (const step of addedSteps) addedIdentities.push(await runAddedStep(step, targetConfig, context));
|
|
614
|
+
return { snapshotData: { executedSteps: [...baselineExecutedSteps, ...addedIdentities] } };
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
//#endregion
|
|
618
|
+
//#region source/management/domains/custom-installation/plan.ts
|
|
619
|
+
/** Builds an `add` operation for a step run for the first time. */
|
|
620
|
+
function buildAddOperation(step) {
|
|
621
|
+
return {
|
|
622
|
+
after: {
|
|
623
|
+
name: step.name,
|
|
624
|
+
script: step.script
|
|
625
|
+
},
|
|
626
|
+
id: `add:${step.name}`,
|
|
627
|
+
kind: "add",
|
|
628
|
+
label: `Run custom installation step "${step.name}"`
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Builds an informational `remove` operation for a step no longer in the target config. No
|
|
633
|
+
* `uninstall` runs from it; it exists so the plan reflects that the step left the configuration.
|
|
634
|
+
*/
|
|
635
|
+
function buildRemoveOperation(step) {
|
|
636
|
+
return {
|
|
637
|
+
before: {
|
|
638
|
+
name: step.name,
|
|
639
|
+
script: step.script
|
|
640
|
+
},
|
|
641
|
+
id: `remove:${step.name}`,
|
|
642
|
+
kind: "remove",
|
|
643
|
+
label: `Custom installation step "${step.name}" no longer in the configuration`
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
/**
|
|
647
|
+
* Resolves the executed-step history to diff the target against. Prefers the reconciliation
|
|
648
|
+
* snapshot when present, and otherwise reconstructs it from the baseline config's own steps.
|
|
649
|
+
*/
|
|
650
|
+
function resolveBaselineExecutedSteps(baseline) {
|
|
651
|
+
const recorded = baseline?.data?.executedSteps;
|
|
652
|
+
if (recorded) return recorded;
|
|
653
|
+
if (baseline && require_webhooks.hasCustomInstallationSteps(baseline.config)) return baseline.config.installation.customInstallationSteps.map((step) => ({
|
|
654
|
+
name: step.name,
|
|
655
|
+
script: step.script
|
|
656
|
+
}));
|
|
657
|
+
return [];
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* Plans the custom installation steps domain by diffing the baseline's executed-step history
|
|
661
|
+
* against the target config's steps, by `name`: `add` for names not seen before, `remove` for
|
|
662
|
+
* names no longer configured. Steps present in both produce no operation and are never re-run.
|
|
663
|
+
*/
|
|
664
|
+
function planCustomInstallationSteps(input, _context) {
|
|
665
|
+
const { path, baseline, targetConfig } = input;
|
|
666
|
+
const baselineExecutedSteps = resolveBaselineExecutedSteps(baseline);
|
|
667
|
+
const targetSteps = targetConfig && require_webhooks.hasCustomInstallationSteps(targetConfig) ? targetConfig.installation.customInstallationSteps : [];
|
|
668
|
+
const baselineNames = new Set(baselineExecutedSteps.map((s) => s.name));
|
|
669
|
+
const targetNames = new Set(targetSteps.map((s) => s.name));
|
|
670
|
+
const operations = [...targetSteps.filter((step) => !baselineNames.has(step.name)).map((step) => buildAddOperation(step)), ...baselineExecutedSteps.filter((step) => !targetNames.has(step.name)).map((step) => buildRemoveOperation(step))];
|
|
671
|
+
return Promise.resolve({
|
|
672
|
+
kind: "planned",
|
|
673
|
+
plan: {
|
|
674
|
+
baselineExecutedSteps,
|
|
675
|
+
operations,
|
|
676
|
+
path,
|
|
677
|
+
targetConfig
|
|
678
|
+
}
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
|
|
572
682
|
//#endregion
|
|
573
683
|
//#region source/management/domains/custom-installation/branch.ts
|
|
684
|
+
/**
|
|
685
|
+
* Leaf step that reconciles the custom installation steps domain as a whole via `plan`/`apply`.
|
|
686
|
+
* It participates only in the upgrade tree; the per-script leaves handle install and uninstall.
|
|
687
|
+
*/
|
|
688
|
+
const reconciliationStep = defineLeafStep({
|
|
689
|
+
apply: applyCustomInstallationSteps,
|
|
690
|
+
install: (config) => {
|
|
691
|
+
if (!require_webhooks.hasCustomInstallationSteps(config)) return { executedSteps: [] };
|
|
692
|
+
return { executedSteps: config.installation.customInstallationSteps.map((step) => ({
|
|
693
|
+
name: step.name,
|
|
694
|
+
script: step.script
|
|
695
|
+
})) };
|
|
696
|
+
},
|
|
697
|
+
meta: {
|
|
698
|
+
install: {
|
|
699
|
+
description: "Records which custom installation steps ran, so future upgrades can detect additions and removals",
|
|
700
|
+
label: "Reconcile Custom Installation Steps"
|
|
701
|
+
},
|
|
702
|
+
upgrade: {
|
|
703
|
+
description: "Runs custom installation steps added since the last version",
|
|
704
|
+
label: "Reconcile Custom Installation Steps"
|
|
705
|
+
}
|
|
706
|
+
},
|
|
707
|
+
name: "reconciliation",
|
|
708
|
+
plan: planCustomInstallationSteps
|
|
709
|
+
});
|
|
574
710
|
/** Root custom installation step that executes custom installation scripts. */
|
|
575
711
|
const customInstallationStepBase = defineBranchStep({
|
|
576
712
|
children: [],
|
|
@@ -583,18 +719,33 @@ const customInstallationStepBase = defineBranchStep({
|
|
|
583
719
|
uninstall: {
|
|
584
720
|
description: "Executes custom uninstallation scripts defined in the application configuration",
|
|
585
721
|
label: "Custom Uninstallation Steps"
|
|
722
|
+
},
|
|
723
|
+
upgrade: {
|
|
724
|
+
description: "Reconciles custom installation steps added or removed between versions",
|
|
725
|
+
label: "Custom Installation Steps"
|
|
586
726
|
}
|
|
587
727
|
},
|
|
588
728
|
name: "customInstallationSteps"
|
|
589
729
|
});
|
|
590
730
|
/**
|
|
591
|
-
* Creates the custom installation step with dynamic children based on config.
|
|
592
|
-
*
|
|
593
|
-
|
|
594
|
-
|
|
731
|
+
* Creates the custom installation step with dynamic children based on config. `executedSteps` is
|
|
732
|
+
* the recorded run history, only passed when building the full-uninstall tree.
|
|
733
|
+
* `includeReconciliation` adds the reconciliation leaf, which only runs on upgrade; install and
|
|
734
|
+
* uninstall leave it out.
|
|
735
|
+
*/
|
|
736
|
+
function createCustomInstallationStep(config, executedSteps = [], includeReconciliation = false) {
|
|
737
|
+
const children = executedSteps.length > 0 ? [...executedSteps].reverse().map((identity) => {
|
|
738
|
+
const currentStep = require_webhooks.hasCustomInstallationSteps(config) ? config.installation.customInstallationSteps.find((step) => step.name === identity.name) : void 0;
|
|
739
|
+
return createCustomScriptStep(currentStep ?? {
|
|
740
|
+
description: "Previously executed custom installation step, no longer present in the configuration.",
|
|
741
|
+
name: identity.name,
|
|
742
|
+
script: identity.script
|
|
743
|
+
});
|
|
744
|
+
}) : [...createCustomScriptSteps(config), ...includeReconciliation ? [reconciliationStep] : []];
|
|
595
745
|
return {
|
|
596
746
|
...customInstallationStepBase,
|
|
597
|
-
children
|
|
747
|
+
children,
|
|
748
|
+
isConfigured: (candidateConfig) => require_webhooks.hasCustomInstallationSteps(candidateConfig) || executedSteps.length > 0
|
|
598
749
|
};
|
|
599
750
|
}
|
|
600
751
|
|
|
@@ -845,6 +996,18 @@ function enumerateComponents(adminUi) {
|
|
|
845
996
|
label: "menu",
|
|
846
997
|
ref: { kind: "menu" }
|
|
847
998
|
});
|
|
999
|
+
for (const aclEntry of adminUi.acl ?? []) {
|
|
1000
|
+
const key = `acl.${aclEntry.id}`;
|
|
1001
|
+
components.set(key, {
|
|
1002
|
+
config: aclEntry,
|
|
1003
|
+
key,
|
|
1004
|
+
label: `acl resource "${aclEntry.id}"`,
|
|
1005
|
+
ref: {
|
|
1006
|
+
id: aclEntry.id,
|
|
1007
|
+
kind: "acl"
|
|
1008
|
+
}
|
|
1009
|
+
});
|
|
1010
|
+
}
|
|
848
1011
|
for (const entity of ADMIN_UI_ENTITIES) {
|
|
849
1012
|
const entityConfig = adminUi[entity];
|
|
850
1013
|
if (!entityConfig) continue;
|
|
@@ -1120,15 +1283,24 @@ async function reconcileProviderSubResources(baseline, target, targetMetadata, b
|
|
|
1120
1283
|
}
|
|
1121
1284
|
await removeDroppedMetadata(providerData, options.type, target.events, baseline.events, targetMetadata, baselineMetadata, context);
|
|
1122
1285
|
}
|
|
1123
|
-
/**
|
|
1286
|
+
/**
|
|
1287
|
+
* Finds the deployed I/O Events provider for a target, preferring the current workspace-scoped
|
|
1288
|
+
* instance id over the legacy (workspace-less) one, and a metadata-bearing provider over an empty
|
|
1289
|
+
* duplicate that shares its instance id.
|
|
1290
|
+
*/
|
|
1124
1291
|
function resolveDeployedProvider(target, targetMetadata, baselineMetadata, workspaceId, existingData) {
|
|
1125
|
-
const
|
|
1292
|
+
const orderedCandidates = [
|
|
1126
1293
|
require_utils.generateInstanceId(targetMetadata, target.provider, workspaceId),
|
|
1127
|
-
require_utils.generateInstanceIdDeprecated(targetMetadata, target.provider),
|
|
1128
1294
|
require_utils.generateInstanceId(baselineMetadata, target.provider, workspaceId),
|
|
1295
|
+
require_utils.generateInstanceIdDeprecated(targetMetadata, target.provider),
|
|
1129
1296
|
require_utils.generateInstanceIdDeprecated(baselineMetadata, target.provider)
|
|
1130
|
-
]
|
|
1131
|
-
|
|
1297
|
+
];
|
|
1298
|
+
for (const candidate of orderedCandidates) {
|
|
1299
|
+
const matches = existingData.providersWithMetadata.filter((provider) => provider.instance_id === candidate);
|
|
1300
|
+
if (matches.length === 0) continue;
|
|
1301
|
+
return matches.find((provider) => provider.metadata.length > 0) ?? matches[0];
|
|
1302
|
+
}
|
|
1303
|
+
return null;
|
|
1132
1304
|
}
|
|
1133
1305
|
/** The fully-qualified I/O Events code set for a group of events under a provider type. */
|
|
1134
1306
|
function eventCodeSet(events, type, metadata) {
|
|
@@ -2945,22 +3117,26 @@ const webhooksStep = defineBranchStep({
|
|
|
2945
3117
|
//#endregion
|
|
2946
3118
|
//#region source/management/installation/root.ts
|
|
2947
3119
|
/**
|
|
2948
|
-
* Creates the default child steps built-in in the library with dynamic children based on the
|
|
3120
|
+
* Creates the default child steps built-in in the library with dynamic children based on the
|
|
3121
|
+
* config. `executedCustomInstallationSteps` is only meaningful for a full uninstall (see
|
|
3122
|
+
* {@link createRootUninstallationStep}). `includeReconciliation` adds the reconciliation leaf,
|
|
3123
|
+
* which only runs on upgrade.
|
|
2949
3124
|
*/
|
|
2950
|
-
function createDefaultChildSteps(config) {
|
|
3125
|
+
function createDefaultChildSteps(config, executedCustomInstallationSteps = [], includeReconciliation = false) {
|
|
2951
3126
|
return [
|
|
2952
3127
|
eventingStep,
|
|
2953
3128
|
webhooksStep,
|
|
2954
3129
|
adminUiStep,
|
|
2955
|
-
createCustomInstallationStep(config)
|
|
3130
|
+
createCustomInstallationStep(config, executedCustomInstallationSteps, includeReconciliation)
|
|
2956
3131
|
];
|
|
2957
3132
|
}
|
|
2958
3133
|
/**
|
|
2959
|
-
* Creates a root installation step with dynamic children based on the config.
|
|
3134
|
+
* Creates a root installation step with dynamic children based on the config. `forUpgrade` adds the
|
|
3135
|
+
* reconciliation leaf, which only runs on upgrade.
|
|
2960
3136
|
*/
|
|
2961
|
-
function createRootInstallationStep(config) {
|
|
3137
|
+
function createRootInstallationStep(config, { forUpgrade = false } = {}) {
|
|
2962
3138
|
return defineBranchStep({
|
|
2963
|
-
children: createDefaultChildSteps(config),
|
|
3139
|
+
children: createDefaultChildSteps(config, [], forUpgrade),
|
|
2964
3140
|
meta: {
|
|
2965
3141
|
install: {
|
|
2966
3142
|
description: "App installation workflow",
|
|
@@ -2980,10 +3156,14 @@ function createRootInstallationStep(config) {
|
|
|
2980
3156
|
}
|
|
2981
3157
|
/**
|
|
2982
3158
|
* Creates a root uninstallation step with dynamic children based on the config.
|
|
3159
|
+
*
|
|
3160
|
+
* `executedCustomInstallationSteps` is the persisted history of every custom installation step
|
|
3161
|
+
* that ever ran (from the lifecycle baseline snapshot). Passing it lets a full unassociate reach
|
|
3162
|
+
* steps that ran in a previous version but were since removed from the config.
|
|
2983
3163
|
*/
|
|
2984
|
-
function createRootUninstallationStep(config) {
|
|
3164
|
+
function createRootUninstallationStep(config, executedCustomInstallationSteps = []) {
|
|
2985
3165
|
return defineBranchStep({
|
|
2986
|
-
children: createDefaultChildSteps(config),
|
|
3166
|
+
children: createDefaultChildSteps(config, executedCustomInstallationSteps),
|
|
2987
3167
|
meta: { install: {
|
|
2988
3168
|
description: "App uninstallation workflow",
|
|
2989
3169
|
label: "Uninstallation"
|
|
@@ -3071,8 +3251,8 @@ async function runInstallation(options) {
|
|
|
3071
3251
|
* Creates an initial uninstallation state from the config and step definitions.
|
|
3072
3252
|
*/
|
|
3073
3253
|
function createInitialUninstallationState(options) {
|
|
3074
|
-
const { config } = options;
|
|
3075
|
-
const rootStep = createRootUninstallationStep(config);
|
|
3254
|
+
const { config, executedCustomInstallationSteps = [] } = options;
|
|
3255
|
+
const rootStep = createRootUninstallationStep(config, executedCustomInstallationSteps);
|
|
3076
3256
|
return createInitialState({
|
|
3077
3257
|
config,
|
|
3078
3258
|
mode: "uninstall",
|
|
@@ -3083,8 +3263,8 @@ function createInitialUninstallationState(options) {
|
|
|
3083
3263
|
* Runs the full uninstallation workflow. Returns the final state (never throws).
|
|
3084
3264
|
*/
|
|
3085
3265
|
function runUninstallation(options) {
|
|
3086
|
-
const { installationContext, config, initialState, hooks } = options;
|
|
3087
|
-
const rootStep = createRootUninstallationStep(config);
|
|
3266
|
+
const { installationContext, config, initialState, hooks, executedCustomInstallationSteps = [] } = options;
|
|
3267
|
+
const rootStep = createRootUninstallationStep(config, executedCustomInstallationSteps);
|
|
3088
3268
|
return executeUninstallWorkflow({
|
|
3089
3269
|
config,
|
|
3090
3270
|
failureKey: "INSTALLATION_FAILED",
|