@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.
Files changed (54) hide show
  1. package/CHANGELOG.md +31 -5
  2. package/dist/cjs/actions/app-config/index.cjs +3 -3
  3. package/dist/cjs/actions/app-config/index.d.cts +3 -4
  4. package/dist/cjs/actions/association/index.d.cts +2 -3
  5. package/dist/cjs/actions/config/index.d.cts +2 -3
  6. package/dist/cjs/actions/installation/index.cjs +14 -7
  7. package/dist/cjs/actions/installation/index.d.cts +5 -5
  8. package/dist/cjs/actions/scope-tree/index.d.cts +2 -3
  9. package/dist/cjs/{app-Cf3EmtUh.d.cts → app-DwSqUkJA.d.cts} +122 -16
  10. package/dist/cjs/commands/index.cjs +91 -51
  11. package/dist/cjs/commands/templates/admin-ui/web-src/.babelrc +14 -0
  12. package/dist/cjs/commands/templates/business-configuration/config.js.template +7 -1
  13. package/dist/cjs/{common-B70f39vI.cjs → common-VSsQEHDv.cjs} +15 -2
  14. package/dist/cjs/config/index.browser.d.cts +1 -1
  15. package/dist/cjs/config/index.node.cjs +4 -3
  16. package/dist/cjs/config/index.node.d.cts +104 -50
  17. package/dist/{es/define-DSU8Kgu0.d.mts → cjs/define-Cc3AaVmY.d.cts} +1 -1
  18. package/dist/{es/index-COLnI6Ok.d.mts → cjs/index-C7dqTDHu.d.cts} +25 -3
  19. package/dist/cjs/index.d.cts +10 -10
  20. package/dist/cjs/{index.node-CXeIG8SS.cjs → index.node-vcOo1rt0.cjs} +1 -1
  21. package/dist/cjs/installation-D72LoQ_1.d.cts +39 -0
  22. package/dist/cjs/management/index.cjs +1 -1
  23. package/dist/cjs/management/index.d.cts +1 -1
  24. package/dist/cjs/{management-BhMdRr8i.cjs → management-Bki3hlxL.cjs} +207 -27
  25. package/dist/cjs/{openapi-DVJUTOXY.cjs → openapi-CAXgKam0.cjs} +317 -390
  26. package/dist/cjs/{validate-Dff0nrqM.cjs → validate-CwWYtRsS.cjs} +33 -2
  27. package/dist/cjs/{webhooks-E1KDx3Yu.cjs → webhooks-Bcq2Qy7q.cjs} +69 -8
  28. package/dist/es/actions/app-config/index.d.mts +3 -4
  29. package/dist/es/actions/app-config/index.mjs +3 -3
  30. package/dist/es/actions/association/index.d.mts +2 -3
  31. package/dist/es/actions/config/index.d.mts +2 -3
  32. package/dist/es/actions/installation/index.d.mts +5 -5
  33. package/dist/es/actions/installation/index.mjs +14 -7
  34. package/dist/es/actions/scope-tree/index.d.mts +2 -3
  35. package/dist/es/{app-Cf3EmtUh.d.mts → app-DwSqUkJA.d.mts} +122 -16
  36. package/dist/es/commands/index.mjs +92 -52
  37. package/dist/es/commands/templates/admin-ui/web-src/.babelrc +14 -0
  38. package/dist/es/commands/templates/business-configuration/config.js.template +7 -1
  39. package/dist/es/{common-BVG9tiX0.mjs → common-dy6NrZt8.mjs} +10 -3
  40. package/dist/es/config/index.browser.d.mts +1 -1
  41. package/dist/es/config/index.node.d.mts +104 -50
  42. package/dist/es/config/index.node.mjs +4 -4
  43. package/dist/{cjs/define-B-_oKmCe.d.cts → es/define-Bq1zw9Lr.d.mts} +1 -1
  44. package/dist/{cjs/index-CkwCGvut.d.cts → es/index-BryddQId.d.mts} +25 -3
  45. package/dist/es/index.d.mts +10 -10
  46. package/dist/es/{index.node-DRTF5Hue.mjs → index.node-CW46zuxW.mjs} +1 -1
  47. package/dist/es/installation-DqVDJ1ur.d.mts +39 -0
  48. package/dist/es/management/index.d.mts +1 -1
  49. package/dist/es/management/index.mjs +1 -1
  50. package/dist/es/{management-BTWQdJNO.mjs → management-DgwAhaaJ.mjs} +207 -27
  51. package/dist/es/{openapi-D18LT0Wp.mjs → openapi-BnR9OUac.mjs} +317 -390
  52. package/dist/es/{validate-8AXMGEwr.mjs → validate-NzW1FQwL.mjs} +29 -4
  53. package/dist/es/{webhooks-BQ8kSN2Z.mjs → webhooks-CHZ1SXxw.mjs} +64 -9
  54. package/package.json +19 -19
@@ -14,7 +14,7 @@
14
14
 
15
15
  const require_rolldown_runtime = require('./rolldown-runtime-CDQd2xEI.cjs');
16
16
  const require_schemas = require('./schemas-3e49M8zz.cjs');
17
- const require_webhooks = require('./webhooks-E1KDx3Yu.cjs');
17
+ const require_webhooks = require('./webhooks-Bcq2Qy7q.cjs');
18
18
  let _adobe_aio_commerce_lib_config = require("@adobe/aio-commerce-lib-config");
19
19
  let _adobe_aio_commerce_lib_core_error = require("@adobe/aio-commerce-lib-core/error");
20
20
  let valibot = require("valibot");
@@ -51,7 +51,7 @@ const MetadataSchema = valibot.object({
51
51
  description: valibot.pipe(nonEmptyString("metadata description"), valibot.maxLength(MAX_DESCRIPTION_LENGTH, `The metadata description must not be longer than ${MAX_DESCRIPTION_LENGTH} characters`)),
52
52
  displayName: valibot.pipe(nonEmptyString("application display name"), valibot.maxLength(MAX_DISPLAY_NAME_LENGTH, `The application display name must not be longer than ${MAX_DISPLAY_NAME_LENGTH} characters`)),
53
53
  id: valibot.pipe(require_schemas.alphaNumericOrHyphenSchema("application id (metadata.id)"), valibot.maxLength(MAX_ID_LENGTH, `The application id must not be longer than ${MAX_ID_LENGTH} characters`)),
54
- upgradeMode: valibot.optional(valibot.picklist(["auto", "manual"]), "auto"),
54
+ upgradeMode: valibot.optional(valibot.picklist(["auto", "manual"]), "manual"),
55
55
  version: valibot.pipe(nonEmptyString("version"), valibot.regex(SEMVER_REGEX, "The version must follow semantic versioning (semver) format: Major.Minor.Patch (e.g., '1.0.0', '2.3.1')"))
56
56
  });
57
57
  /**
@@ -121,6 +121,16 @@ const CommerceAppConfigSchema = valibot.looseObject({
121
121
  webhooks: valibot.optional(require_webhooks.WebhooksSchema)
122
122
  });
123
123
  /**
124
+ * The schema used to validate a commerce app config recovered from a
125
+ * persisted lifecycle snapshot (installation/upgrade baseline), where
126
+ * `businessConfig.schema` `dynamicList` fields may have lost their
127
+ * `options`/`default` functions to a JSON round trip through storage.
128
+ */
129
+ const RecordedCommerceAppConfigSchema = valibot.looseObject({
130
+ ...CommerceAppConfigSchema.entries,
131
+ businessConfig: valibot.optional(_adobe_aio_commerce_lib_config.RecordedSchemaBusinessConfig)
132
+ });
133
+ /**
124
134
  * Returns true if the given config domains require installation, false otherwise.
125
135
  * @param domains - The config domains to check.
126
136
  */
@@ -170,6 +180,21 @@ function validateCommerceAppConfig(config) {
170
180
  return validatedConfig.output;
171
181
  }
172
182
  /**
183
+ * Validates a commerce app config recovered from a persisted lifecycle
184
+ * snapshot (installation/upgrade baseline) against the schema.
185
+ *
186
+ * @param config - The configuration object to validate.
187
+ * @returns The validated and typed configuration output model.
188
+ *
189
+ * @throws {CommerceSdkValidationError} If the configuration is invalid, with
190
+ * detailed validation issues included.
191
+ */
192
+ function validateRecordedCommerceAppConfig(config) {
193
+ const validatedConfig = valibot.safeParse(RecordedCommerceAppConfigSchema, config);
194
+ if (!validatedConfig.success) throw new _adobe_aio_commerce_lib_core_error.CommerceSdkValidationError("Invalid commerce app config", { issues: validatedConfig.issues });
195
+ return validatedConfig.output;
196
+ }
197
+ /**
173
198
  * Validates a specific domain configuration within the commerce app config.
174
199
  *
175
200
  * This function validates only a specific domain's configuration rather than
@@ -274,4 +299,10 @@ Object.defineProperty(exports, 'validateCommerceAppConfigDomain', {
274
299
  get: function () {
275
300
  return validateCommerceAppConfigDomain;
276
301
  }
302
+ });
303
+ Object.defineProperty(exports, 'validateRecordedCommerceAppConfig', {
304
+ enumerable: true,
305
+ get: function () {
306
+ return validateRecordedCommerceAppConfig;
307
+ }
277
308
  });
@@ -16,10 +16,20 @@ const require_rolldown_runtime = require('./rolldown-runtime-CDQd2xEI.cjs');
16
16
  const require_schemas = require('./schemas-3e49M8zz.cjs');
17
17
  let valibot = require("valibot");
18
18
  valibot = require_rolldown_runtime.__toESM(valibot, 1);
19
+ let _adobe_aio_commerce_lib_admin_ui_api = require("@adobe/aio-commerce-lib-admin-ui/api");
19
20
  let _adobe_aio_commerce_lib_admin_ui_menu = require("@adobe/aio-commerce-lib-admin-ui/menu");
20
21
  let _adobe_aio_commerce_lib_core_commerce = require("@adobe/aio-commerce-lib-core/commerce");
21
22
 
22
23
  //#region source/config/schema/admin-ui.ts
24
+ /**
25
+ * Whether the given items have distinct ids once Commerce sanitizes them into resource ids.
26
+ * Catches ids that differ only by case or by a character that sanitizes to `_`. Used by the
27
+ * component fields whose ids are otherwise unconstrained (grid columns, mass actions, view buttons).
28
+ */
29
+ function hasUniqueSanitizedIds(items) {
30
+ const ids = items.map((item) => (0, _adobe_aio_commerce_lib_admin_ui_api.sanitizeSegment)(item.id));
31
+ return new Set(ids).size === ids.length;
32
+ }
23
33
  const SANDBOX_PERMISSION_VALUES = [
24
34
  "allow-downloads",
25
35
  "allow-modals",
@@ -57,7 +67,7 @@ const GridColumnSchema = valibot.strictObject({
57
67
  type: ColumnTypeSchema
58
68
  });
59
69
  const GridColumnsSchema = valibot.object({
60
- columns: valibot.pipe(valibot.array(GridColumnSchema), valibot.minLength(1, "At least one grid column is required")),
70
+ columns: valibot.pipe(valibot.array(GridColumnSchema), valibot.minLength(1, "At least one grid column is required"), valibot.check((items) => hasUniqueSanitizedIds(items), "Grid column ids must be unique after Commerce id sanitization.")),
61
71
  description: require_schemas.nonEmptyStringValueSchema("grid columns description"),
62
72
  label: require_schemas.nonEmptyStringValueSchema("grid columns label"),
63
73
  runtimeAction: require_schemas.nonEmptyStringValueSchema("runtime action")
@@ -122,11 +132,11 @@ const OrderViewButtonSchema = valibot.variant("type", [valibot.strictObject({
122
132
  timeout: valibot.optional(require_schemas.positiveNumberValueSchema("timeout")),
123
133
  type: valibot.literal("worker")
124
134
  })]);
125
- const MassActionsSchema = valibot.pipe(valibot.array(MassActionSchema), valibot.check((items) => new Set(items.map((item) => item.id)).size === items.length, "Mass action ids must be unique."));
135
+ const MassActionsSchema = valibot.pipe(valibot.array(MassActionSchema), valibot.check((items) => hasUniqueSanitizedIds(items), "Mass action ids must be unique after Commerce id sanitization."));
126
136
  const AdminUiOrderSchema = valibot.object({
127
137
  gridColumns: valibot.optional(GridColumnsSchema),
128
138
  massActions: valibot.optional(MassActionsSchema),
129
- viewButtons: valibot.optional(valibot.pipe(valibot.array(OrderViewButtonSchema), valibot.check((items) => new Set(items.map((item) => item.id)).size === items.length, "Order view button ids must be unique.")))
139
+ viewButtons: valibot.optional(valibot.pipe(valibot.array(OrderViewButtonSchema), valibot.check((items) => hasUniqueSanitizedIds(items), "Order view button ids must be unique after Commerce id sanitization.")))
130
140
  });
131
141
  const AdminUiProductSchema = valibot.object({
132
142
  gridColumns: valibot.optional(GridColumnsSchema),
@@ -151,26 +161,71 @@ const MenuSchema = valibot.object({
151
161
  parentMenu: valibot.optional(valibot.picklist(_adobe_aio_commerce_lib_admin_ui_menu.COMMERCE_MENUS, "parentMenu must be a known Commerce Admin menu ID")),
152
162
  sandboxPermissions: valibot.optional(SandboxPermissionsSchema)
153
163
  });
164
+ const AclResourceIdSchema = valibot.pipe(require_schemas.nonEmptyStringValueSchema("acl resource ID"), valibot.regex(/^[a-z0-9_]+$/, "ACL resource ID may contain only lowercase letters, digits, and \"_\""));
165
+ const ACL_LABEL_MIN_LENGTH = 3;
166
+ const ACL_LABEL_MAX_LENGTH = 50;
167
+ const AclResourceLabelSchema = valibot.pipe(require_schemas.nonEmptyStringValueSchema("acl resource label"), valibot.minLength(ACL_LABEL_MIN_LENGTH, `acl resource label must be at least ${ACL_LABEL_MIN_LENGTH} characters`), valibot.maxLength(ACL_LABEL_MAX_LENGTH, `acl resource label must be at most ${ACL_LABEL_MAX_LENGTH} characters`));
168
+ /** A single custom ACL resource leaf. Leaves never nest — this is what keeps grouping one level deep. */
169
+ const AclResourceLeafSchema = valibot.strictObject({
170
+ id: AclResourceIdSchema,
171
+ label: AclResourceLabelSchema
172
+ });
173
+ /** A top-level acl entry: a leaf, or a group carrying leaf children (exactly one level of nesting). */
174
+ const AclResourceEntrySchema = valibot.strictObject({
175
+ children: valibot.optional(valibot.pipe(valibot.array(AclResourceLeafSchema), valibot.minLength(1, "An ACL resource group must contain at least one child"), valibot.check((items) => new Set(items.map((i) => i.id)).size === items.length, "Child ACL resource ids must be unique within a group."))),
176
+ id: AclResourceIdSchema,
177
+ label: AclResourceLabelSchema
178
+ });
179
+ /**
180
+ * The Commerce ACL resource ids an `acl` config resolves to, relative to the app root: every
181
+ * top-level entry and group node contributes its own id, and every group child contributes the
182
+ * `<group>_<child>` id Commerce builds by joining segments with "_". Comparing these catches ids
183
+ * that look distinct but collapse to the same Commerce resource (e.g. a leaf `reports_export` vs a
184
+ * group `reports` with a child `export`). Ids are already canonical (see {@link AclResourceIdSchema}).
185
+ */
186
+ function aclResourceIdentities(entries) {
187
+ const ids = [];
188
+ for (const entry of entries) {
189
+ ids.push(entry.id);
190
+ for (const child of entry.children ?? []) ids.push(`${entry.id}_${child.id}`);
191
+ }
192
+ return ids;
193
+ }
194
+ const AdminUiAclSchema = valibot.pipe(valibot.array(AclResourceEntrySchema), valibot.minLength(1, "At least one ACL resource is required when acl is defined"), valibot.check((items) => new Set(items.map((i) => i.id)).size === items.length, "Top-level ACL resource ids must be unique."), valibot.check((items) => {
195
+ const ids = aclResourceIdentities(items);
196
+ return new Set(ids).size === ids.length;
197
+ }, "Custom ACL resource ids must stay unique after Commerce derivation: a top-level resource id must not equal a group's \"<group>_<child>\" combination."));
154
198
  /**
155
199
  * Schema for the `adminUi` config section.
156
- * Supports grid column extensions, mass actions, order view buttons, and menu on `commerce/backend-ui/2`.
200
+ * Supports grid column extensions, mass actions, order view buttons, menu, and custom ACL resources on `commerce/backend-ui/2`.
157
201
  */
158
202
  const AdminUiSchema = valibot.object({
203
+ acl: valibot.optional(AdminUiAclSchema),
159
204
  customer: valibot.optional(AdminUiCustomerSchema),
160
205
  menu: valibot.optional(MenuSchema),
161
206
  order: valibot.optional(AdminUiOrderSchema),
162
207
  product: valibot.optional(AdminUiProductSchema)
163
208
  });
164
209
  /**
165
- * Check whether the config declares at least one Admin UI component (menu, grid
166
- * columns, mass actions, or view buttons). A component-less `adminUi` block is
167
- * treated as absent — it registers nothing.
210
+ * Check whether the config declares an Admin UI component that requires the
211
+ * `commerce/backend-ui/2` extension point — a menu, grid columns, mass actions,
212
+ * or view buttons. Custom ACL resources are deliberately excluded: they reach
213
+ * Commerce through the `extensibility/1` app-config payload, not backend-ui/2,
214
+ * so an acl-only config needs no backend-ui/2 registration.
168
215
  */
169
- function hasAdminUi(config) {
216
+ function hasBackendUiV2Components(config) {
170
217
  const { adminUi } = config;
171
218
  if (!adminUi) return false;
172
219
  return Boolean(adminUi.menu || adminUi.order?.gridColumns || adminUi.order?.massActions?.length || adminUi.order?.viewButtons?.length || adminUi.product?.gridColumns || adminUi.product?.massActions?.length || adminUi.customer?.gridColumns || adminUi.customer?.massActions?.length);
173
220
  }
221
+ /**
222
+ * Check whether the config declares at least one Admin UI component (menu, grid
223
+ * columns, mass actions, view buttons, or custom ACL resources). A component-less `adminUi` block is
224
+ * treated as absent — it registers nothing.
225
+ */
226
+ function hasAdminUi(config) {
227
+ return hasBackendUiV2Components(config) || Boolean(config.adminUi?.acl?.length);
228
+ }
174
229
 
175
230
  //#endregion
176
231
  //#region source/config/schema/eventing.ts
@@ -504,6 +559,12 @@ Object.defineProperty(exports, 'hasAdminUi', {
504
559
  return hasAdminUi;
505
560
  }
506
561
  });
562
+ Object.defineProperty(exports, 'hasBackendUiV2Components', {
563
+ enumerable: true,
564
+ get: function () {
565
+ return hasBackendUiV2Components;
566
+ }
567
+ });
507
568
  Object.defineProperty(exports, 'hasCommerceEvents', {
508
569
  enumerable: true,
509
570
  get: function () {
@@ -13,7 +13,7 @@
13
13
  */
14
14
 
15
15
  import "../../index-CgsSXApi.mjs";
16
- import { n as CommerceAppConfig } from "../../app-Cf3EmtUh.mjs";
16
+ import { n as CommerceAppConfig } from "../../app-DwSqUkJA.mjs";
17
17
  import { RuntimeActionParams } from "@adobe/aio-commerce-lib-core/params";
18
18
  //#region source/actions/app-config/router.d.ts
19
19
  /** The arguments required to create the runtime action for the app-config action. */
@@ -26,6 +26,5 @@ type RuntimeActionFactoryArgs = {
26
26
  * Factory to create the route handler for the `app-config` action.
27
27
  * @param args - The arguments required to create the runtime action.
28
28
  */
29
- declare const appConfigRuntimeAction: (args: RuntimeActionFactoryArgs) => (params: RuntimeActionParams) => Promise<import("@adobe/aio-commerce-lib-core/responses").ActionResponse>;
30
- //#endregion
31
- export { appConfigRuntimeAction };
29
+ export declare const appConfigRuntimeAction: (args: RuntimeActionFactoryArgs) => (params: RuntimeActionParams) => Promise<import("@adobe/aio-commerce-lib-core/responses").ActionResponse>;
30
+ //#endregion
@@ -13,7 +13,7 @@
13
13
  */
14
14
 
15
15
  import { n as filterAppConfigByEnv } from "../../environment-C84BPRJZ.mjs";
16
- import { a as getConfigDomains, l as hasBusinessConfigSchema, r as requiresInstallationFromDomains, t as validateCommerceAppConfig } from "../../validate-8AXMGEwr.mjs";
16
+ import { i as requiresInstallationFromDomains, o as getConfigDomains, t as validateCommerceAppConfig, u as hasBusinessConfigSchema } from "../../validate-NzW1FQwL.mjs";
17
17
  import { n as logger, t as HttpActionRouter } from "../../router-BshIPAR1.mjs";
18
18
  import { resolveBusinessConfigSchema } from "@adobe/aio-commerce-lib-config";
19
19
  import * as v from "valibot";
@@ -26,7 +26,7 @@ import { createHash } from "crypto";
26
26
  * Loads the committed OpenAPI spec via dynamic import so it
27
27
  * lands in its own chunk and is not parsed on every cold start.
28
28
  */
29
- const importOpenApi = () => import("../../openapi-D18LT0Wp.mjs");
29
+ const importOpenApi = () => import("../../openapi-BnR9OUac.mjs");
30
30
  /** Matches component schema `$ref` strings, capturing the schema name. */
31
31
  const SCHEMA_REF_PATTERN = /"#\/components\/schemas\/(\w+)"/g;
32
32
  /**
@@ -77,7 +77,7 @@ function pruneUnusedTags(spec) {
77
77
  * @param domains - The active config domains.
78
78
  */
79
79
  function getOpenApiCacheKey(domains) {
80
- const input = `2.0.0-beta-20260820174436:${[...domains].sort().join(",")}:3.0.0`;
80
+ const input = `2.0.0:${[...domains].sort().join(",")}:3.0.0`;
81
81
  return createHash("sha256").update(input).digest("hex").slice(0, 8);
82
82
  }
83
83
  /** Returns the server URL to be set in the OpenAPI spec, based on the current namespace. */
@@ -22,6 +22,5 @@ import { RuntimeActionParams } from "@adobe/aio-commerce-lib-core/params";
22
22
  * and `DELETE /` clears it on unassociation. Runtime actions consume the data
23
23
  * via `getCommerceInstance` / `getCommerceClient` from the root entrypoint.
24
24
  */
25
- declare const associationRuntimeAction: () => (params: RuntimeActionParams) => Promise<import("@adobe/aio-commerce-lib-core/responses").ActionResponse>;
26
- //#endregion
27
- export { associationRuntimeAction };
25
+ export declare const associationRuntimeAction: () => (params: RuntimeActionParams) => Promise<import("@adobe/aio-commerce-lib-core/responses").ActionResponse>;
26
+ //#endregion
@@ -26,6 +26,5 @@ type ConfigActionFactoryArgs = {
26
26
  * Factory to create the route handler for the `config` action.
27
27
  * @param args - The arguments required to create the runtime action.
28
28
  */
29
- declare const configRuntimeAction: (args: ConfigActionFactoryArgs) => (params: RuntimeActionParams) => Promise<import("@adobe/aio-commerce-lib-core/responses").ActionResponse>;
30
- //#endregion
31
- export { configRuntimeAction };
29
+ export declare const configRuntimeAction: (args: ConfigActionFactoryArgs) => (params: RuntimeActionParams) => Promise<import("@adobe/aio-commerce-lib-core/responses").ActionResponse>;
30
+ //#endregion
@@ -13,8 +13,8 @@
13
13
  */
14
14
 
15
15
  import "../../index-CgsSXApi.mjs";
16
- import { n as CommerceAppConfig, r as CommerceAppConfigOutputModel } from "../../app-Cf3EmtUh.mjs";
17
- import { J as LifecycleContext } from "../../index-COLnI6Ok.mjs";
16
+ import { n as CommerceAppConfig, r as CommerceAppConfigOutputModel } from "../../app-DwSqUkJA.mjs";
17
+ import { J as LifecycleContext } from "../../index-BryddQId.mjs";
18
18
  import "@adobe/aio-commerce-lib-core/responses";
19
19
  import { RuntimeActionParams } from "@adobe/aio-commerce-lib-core/params";
20
20
  //#region source/actions/installation/common.d.ts
@@ -31,11 +31,11 @@ type RuntimeActionFactoryArgs = {
31
31
  * Defines a type-safe custom installation scripts loader.
32
32
  * @param loader - The custom scripts loader implementation.
33
33
  */
34
- declare function defineCustomScriptsLoader(loader: CustomScriptsLoader): CustomScriptsLoader;
34
+ export declare function defineCustomScriptsLoader(loader: CustomScriptsLoader): CustomScriptsLoader;
35
35
  /**
36
36
  * Factory to create the route handler for the `installation` action.
37
37
  * @param args - The arguments required to create the runtime action.
38
38
  */
39
- declare const installationRuntimeAction: (args: RuntimeActionFactoryArgs) => (params: RuntimeActionParams) => Promise<import("@adobe/aio-commerce-lib-core/responses").ActionResponse>;
39
+ export declare const installationRuntimeAction: (args: RuntimeActionFactoryArgs) => (params: RuntimeActionParams) => Promise<import("@adobe/aio-commerce-lib-core/responses").ActionResponse>;
40
40
  //#endregion
41
- export { type CustomScriptsLoader, defineCustomScriptsLoader, installationRuntimeAction };
41
+ export type { CustomScriptsLoader };
@@ -14,9 +14,9 @@
14
14
 
15
15
  import { n as getAssociationData } from "../../repository-BGmy0YeZ.mjs";
16
16
  import { r as nonEmptyStringValueSchema } from "../../schemas-hRovglBF.mjs";
17
- import { t as validateCommerceAppConfig } from "../../validate-8AXMGEwr.mjs";
18
- import { _ as normalizeExpiredAttempt, a as buildWorkflowParams, b as requireState, c as createLifecyclePersistence, d as getStorageKey, f as isPostAppDeployInvocation, g as CURRENT_STATE_KEY, h as getCurrentLifecycleBaseline, i as buildLifecycleContext, l as createLifecycleRuntime, m as createOrchestrationStateStore, o as createInstallationHooks, p as readStateFromStore, s as createInstallationStore, t as DEFAULT_ACTION_NAME, u as createUninstallationStore, v as readOrInitializeState, y as requireCurrentAttempt } from "../../common-BVG9tiX0.mjs";
19
- import { C as callHook, S as isLeafStep, _ as isStepConfigured, a as runValidation, b as setAtPath, d as isSucceededState, f as createRetryState, g as getAtPath, h as createWorkflowError, i as runUninstallation, l as isFailedState, m as createSucceededState, n as createInitialUninstallationState, p as createFailedState, r as runInstallation, t as createInitialInstallationState, u as isInProgressState, v as nowIsoString, x as isBranchStep, y as pathsEqual } from "../../management-BTWQdJNO.mjs";
17
+ import { r as validateRecordedCommerceAppConfig, t as validateCommerceAppConfig } from "../../validate-NzW1FQwL.mjs";
18
+ import { _ as CURRENT_STATE_KEY, a as buildWorkflowParams, b as requireCurrentAttempt, c as createLifecyclePersistence, d as getExecutedCustomInstallationSteps, f as getStorageKey, g as getCurrentLifecycleBaseline, h as createOrchestrationStateStore, i as buildLifecycleContext, l as createLifecycleRuntime, m as readStateFromStore, o as createInstallationHooks, p as isPostAppDeployInvocation, s as createInstallationStore, t as DEFAULT_ACTION_NAME, u as createUninstallationStore, v as normalizeExpiredAttempt, x as requireState, y as readOrInitializeState } from "../../common-dy6NrZt8.mjs";
19
+ import { C as callHook, S as isLeafStep, _ as isStepConfigured, a as runValidation, b as setAtPath, d as isSucceededState, f as createRetryState, g as getAtPath, h as createWorkflowError, i as runUninstallation, l as isFailedState, m as createSucceededState, n as createInitialUninstallationState, p as createFailedState, r as runInstallation, t as createInitialInstallationState, u as isInProgressState, v as nowIsoString, x as isBranchStep, y as pathsEqual } from "../../management-DgwAhaaJ.mjs";
20
20
  import { n as logger, t as HttpActionRouter } from "../../router-BshIPAR1.mjs";
21
21
  import * as v from "valibot";
22
22
  import { CommerceEnvSchema } from "@adobe/aio-commerce-lib-core/commerce";
@@ -367,11 +367,16 @@ async function startUninstallation({ body, logger, rawParams }) {
367
367
  return conflict("Uninstallation is already in progress. Wait for it to complete.");
368
368
  }
369
369
  const { baselineProvider, stateStore } = await createLifecyclePersistence();
370
- const baselineAppConfig = (await getCurrentLifecycleBaseline(stateStore, baselineProvider))?.config;
370
+ const installationSnapshot = await getCurrentLifecycleBaseline(stateStore, baselineProvider);
371
+ const baselineAppConfig = installationSnapshot?.config;
371
372
  const uninstallConfig = baselineAppConfig ?? rawParams.appConfig;
372
373
  if (!uninstallConfig) return internalServerError("Cannot determine what to uninstall: no recorded lifecycle baseline and no app config was provided.");
373
374
  logger.debug(baselineAppConfig ? "Sourcing uninstallation from recorded lifecycle baseline" : "No recorded lifecycle baseline found; falling back to request config");
374
- const initialState = createInitialUninstallationState({ config: validateCommerceAppConfig(uninstallConfig) });
375
+ const executedCustomInstallationSteps = getExecutedCustomInstallationSteps(installationSnapshot?.data);
376
+ const initialState = createInitialUninstallationState({
377
+ config: validateRecordedCommerceAppConfig(uninstallConfig),
378
+ executedCustomInstallationSteps
379
+ });
375
380
  logger.debug(`Created initial uninstall state: ${initialState.id}`);
376
381
  await store.put(getStorageKey(), initialState);
377
382
  const workflowParams = buildWorkflowParams(body, rawParams);
@@ -383,6 +388,7 @@ async function startUninstallation({ body, logger, rawParams }) {
383
388
  __ow_method: "post",
384
389
  __ow_path: "/uninstallation/execution",
385
390
  appConfig: uninstallConfig,
391
+ executedCustomInstallationSteps,
386
392
  initialState
387
393
  },
388
394
  result: false
@@ -396,16 +402,17 @@ async function startUninstallation({ body, logger, rawParams }) {
396
402
  }
397
403
  /** Runs the uninstallation workflow and clears lifecycle state on success. */
398
404
  async function executeUninstallation({ logger, params }) {
399
- const { initialState, appConfig: rawAppConfig, appData, AIO_COMMERCE_API_BASE_URL } = params;
405
+ const { initialState, appConfig: rawAppConfig, appData, AIO_COMMERCE_API_BASE_URL, executedCustomInstallationSteps = [] } = params;
400
406
  if (!initialState) return badRequest("initialState is required for execution");
401
407
  if (!rawAppConfig) return badRequest("appConfig is required for execution");
402
- const appConfig = validateCommerceAppConfig(rawAppConfig);
408
+ const appConfig = validateRecordedCommerceAppConfig(rawAppConfig);
403
409
  const store = await createUninstallationStore();
404
410
  const hooks = createInstallationHooks(store, (msg) => logger.debug(msg));
405
411
  const installationContext = buildLifecycleContext(params, appConfig, logger);
406
412
  logger.debug(`Executing uninstallation ${initialState.id} for app "${appData.projectName}" (workspace: "${appData.workspaceName}", commerce: "${AIO_COMMERCE_API_BASE_URL}")`);
407
413
  const result = await runUninstallation({
408
414
  config: appConfig,
415
+ executedCustomInstallationSteps,
409
416
  hooks,
410
417
  initialState,
411
418
  installationContext
@@ -14,6 +14,5 @@
14
14
 
15
15
  //#region source/actions/scope-tree/index.d.ts
16
16
  /** The handler method for the `scope-tree` action. */
17
- declare const scopeTreeRuntimeAction: (args: import("@adobe/aio-commerce-lib-core/params").RuntimeActionParams) => Promise<import("@adobe/aio-commerce-lib-core/responses").ActionResponse>;
18
- //#endregion
19
- export { scopeTreeRuntimeAction };
17
+ export declare const scopeTreeRuntimeAction: (args: import("@adobe/aio-commerce-lib-core/params").RuntimeActionParams) => Promise<import("@adobe/aio-commerce-lib-core/responses").ActionResponse>;
18
+ //#endregion