@adobe/aio-commerce-lib-app 2.0.0 → 2.1.0-alpha-20260923164312

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 (69) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +4 -0
  3. package/dist/cjs/actions/app-config/index.cjs +3 -3
  4. package/dist/cjs/actions/association/index.cjs +1 -1
  5. package/dist/cjs/actions/config/index.cjs +1 -1
  6. package/dist/cjs/actions/installation/index.cjs +4 -4
  7. package/dist/cjs/actions/scope-tree/index.cjs +4 -3
  8. package/dist/cjs/cli/index.cjs +447 -0
  9. package/dist/cjs/cli/index.d.cts +40 -0
  10. package/dist/cjs/commands/index.cjs +73 -1717
  11. package/dist/cjs/{common-VSsQEHDv.cjs → common-B3KrOG-h.cjs} +1 -1
  12. package/dist/cjs/config/index.node.cjs +3 -3
  13. package/dist/{es/logging-CXesop3u.mjs → cjs/constants-tQUzmimN.cjs} +6 -18
  14. package/dist/cjs/{index.node-vcOo1rt0.cjs → index.node-De5ENMF8.cjs} +2 -2
  15. package/dist/cjs/{logging-Br3xfBNe.cjs → logging-QTsrSwPc.cjs} +0 -16
  16. package/dist/cjs/management/index.cjs +1 -1
  17. package/dist/cjs/{management-Bki3hlxL.cjs → management-DplOGozL.cjs} +11 -10
  18. package/dist/cjs/{validate-CwWYtRsS.cjs → validate-DkmBVWFX.cjs} +1 -1
  19. package/dist/cjs/web-src-DvGBiJI5.cjs +1521 -0
  20. package/dist/cjs/{webhooks-Bcq2Qy7q.cjs → webhooks-zXjrg32x.cjs} +57 -57
  21. package/dist/es/actions/app-config/index.mjs +3 -3
  22. package/dist/es/actions/association/index.mjs +1 -1
  23. package/dist/es/actions/config/index.mjs +1 -1
  24. package/dist/es/actions/installation/index.mjs +4 -4
  25. package/dist/es/actions/scope-tree/index.mjs +3 -2
  26. package/dist/es/cli/index.d.mts +40 -0
  27. package/dist/es/cli/index.mjs +435 -0
  28. package/dist/es/commands/index.mjs +29 -1666
  29. package/dist/es/{common-dy6NrZt8.mjs → common-BWUDGasu.mjs} +1 -1
  30. package/dist/es/config/index.node.mjs +3 -3
  31. package/dist/es/constants-CSQsZaDP.mjs +25 -0
  32. package/dist/es/{index.node-CW46zuxW.mjs → index.node-C5D5IzSs.mjs} +2 -2
  33. package/dist/es/logging-DbJHXSKh.mjs +32 -0
  34. package/dist/es/management/index.mjs +1 -1
  35. package/dist/es/{management-DgwAhaaJ.mjs → management-YDkb15SJ.mjs} +6 -5
  36. package/dist/es/{validate-NzW1FQwL.mjs → validate-Pd7RIA_3.mjs} +1 -1
  37. package/dist/es/web-src-CLEUvMl7.mjs +1345 -0
  38. package/dist/es/{webhooks-CHZ1SXxw.mjs → webhooks-BMBfTqwi.mjs} +58 -58
  39. package/package.json +11 -1
  40. /package/dist/cjs/{commands/templates → templates}/admin-ui/tsconfig.json +0 -0
  41. /package/dist/cjs/{commands/templates → templates}/admin-ui/web-src/.babelrc +0 -0
  42. /package/dist/cjs/{commands/templates → templates}/admin-ui/web-src/index.css +0 -0
  43. /package/dist/cjs/{commands/templates → templates}/admin-ui/web-src/index.html +0 -0
  44. /package/dist/cjs/{commands/templates → templates}/admin-ui/web-src/src/app.jsx +0 -0
  45. /package/dist/cjs/{commands/templates → templates}/admin-ui/web-src/src/components/welcome.jsx +0 -0
  46. /package/dist/cjs/{commands/templates → templates}/admin-ui/web-src/src/pages/main-page.jsx +0 -0
  47. /package/dist/cjs/{commands/templates → templates}/admin-ui/web-src-template.d.ts +0 -0
  48. /package/dist/cjs/{commands/templates → templates}/app-management/app-config.js.template +0 -0
  49. /package/dist/cjs/{commands/templates → templates}/app-management/association.js.template +0 -0
  50. /package/dist/cjs/{commands/templates → templates}/app-management/custom-scripts.js.template +0 -0
  51. /package/dist/cjs/{commands/templates → templates}/app-management/installation.js.template +0 -0
  52. /package/dist/cjs/{commands/templates → templates}/business-configuration/config.js.template +0 -0
  53. /package/dist/cjs/{commands/templates → templates}/business-configuration/scope-tree.js.template +0 -0
  54. /package/dist/cjs/{commands/templates → templates}/typescript/webpack-config.cjs +0 -0
  55. /package/dist/es/{commands/templates → templates}/admin-ui/tsconfig.json +0 -0
  56. /package/dist/es/{commands/templates → templates}/admin-ui/web-src/.babelrc +0 -0
  57. /package/dist/es/{commands/templates → templates}/admin-ui/web-src/index.css +0 -0
  58. /package/dist/es/{commands/templates → templates}/admin-ui/web-src/index.html +0 -0
  59. /package/dist/es/{commands/templates → templates}/admin-ui/web-src/src/app.jsx +0 -0
  60. /package/dist/es/{commands/templates → templates}/admin-ui/web-src/src/components/welcome.jsx +0 -0
  61. /package/dist/es/{commands/templates → templates}/admin-ui/web-src/src/pages/main-page.jsx +0 -0
  62. /package/dist/es/{commands/templates → templates}/admin-ui/web-src-template.d.ts +0 -0
  63. /package/dist/es/{commands/templates → templates}/app-management/app-config.js.template +0 -0
  64. /package/dist/es/{commands/templates → templates}/app-management/association.js.template +0 -0
  65. /package/dist/es/{commands/templates → templates}/app-management/custom-scripts.js.template +0 -0
  66. /package/dist/es/{commands/templates → templates}/app-management/installation.js.template +0 -0
  67. /package/dist/es/{commands/templates → templates}/business-configuration/config.js.template +0 -0
  68. /package/dist/es/{commands/templates → templates}/business-configuration/scope-tree.js.template +0 -0
  69. /package/dist/es/{commands/templates → templates}/typescript/webpack-config.cjs +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @adobe/aio-commerce-lib-app
2
2
 
3
+ ## 2.1.0-alpha-20260923164312
4
+
5
+ ### Minor Changes
6
+
7
+ - [#701](https://github.com/adobe/aio-commerce-sdk/pull/701) [`e63e960`](https://github.com/adobe/aio-commerce-sdk/commit/e63e96013a3592556c531ea27a334090b01e4269) Thanks [@iivvaannxx](https://github.com/iivvaannxx)! - Run your own code in the generated `pre-app-build`, `pre-app-run`, `pre-app-dev` and `post-app-deploy` hooks by adding a `hooks/<hook>` file at the project root, or under an extension point folder to override it for that extension point.
8
+
9
+ ### Patch Changes
10
+
11
+ - [#701](https://github.com/adobe/aio-commerce-sdk/pull/701) [`64f0db4`](https://github.com/adobe/aio-commerce-sdk/commit/64f0db432cc70824955fe208b510e47bce7b7938) Thanks [@iivvaannxx](https://github.com/iivvaannxx)! - Apps now use the correct `NODE_ENV` on every `aio app run`, `aio app dev` and `aio app build`, and a failing hook stops the command. The hooks in generated `ext.config.yaml` files now point to generated JavaScript files.
12
+
3
13
  ## 2.0.0
4
14
 
5
15
  ### Major Changes
package/README.md CHANGED
@@ -14,6 +14,10 @@ npm install @adobe/aio-commerce-lib-app
14
14
 
15
15
  See the [Usage Guide](./docs/usage.md) for more information.
16
16
 
17
+ ## Internal Entrypoints
18
+
19
+ The `@adobe/aio-commerce-lib-app/cli` entrypoint is internal. It only exists for the code this package generates (the App Builder hook files under `.generated/hooks/`), so don't import it directly. Changes to it do not follow semantic versioning.
20
+
17
21
  ## Contributing
18
22
 
19
23
  This package is part of the Adobe Commerce SDK monorepo. Refer to the [Contributing Guide](https://github.com/adobe/aio-commerce-sdk/blob/main/.github/CONTRIBUTING.md) and [Development Guide](https://github.com/adobe/aio-commerce-sdk/blob/main/.github/DEVELOPMENT.md) for information on development setup and guidelines.
@@ -15,13 +15,13 @@
15
15
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
16
16
  const require_rolldown_runtime = require('../../rolldown-runtime-CDQd2xEI.cjs');
17
17
  const require_environment = require('../../environment-B6533pAY.cjs');
18
- const require_validate = require('../../validate-CwWYtRsS.cjs');
18
+ const require_validate = require('../../validate-DkmBVWFX.cjs');
19
19
  const require_router = require('../../router-CxDTb6r1.cjs');
20
20
  let _adobe_aio_commerce_lib_config = require("@adobe/aio-commerce-lib-config");
21
+ let _adobe_aio_commerce_lib_core_responses = require("@adobe/aio-commerce-lib-core/responses");
21
22
  let valibot = require("valibot");
22
23
  valibot = require_rolldown_runtime.__toESM(valibot, 1);
23
24
  let _adobe_aio_commerce_lib_core_commerce = require("@adobe/aio-commerce-lib-core/commerce");
24
- let _adobe_aio_commerce_lib_core_responses = require("@adobe/aio-commerce-lib-core/responses");
25
25
  let crypto = require("crypto");
26
26
 
27
27
  //#region source/actions/app-config/openapi.ts
@@ -80,7 +80,7 @@ function pruneUnusedTags(spec) {
80
80
  * @param domains - The active config domains.
81
81
  */
82
82
  function getOpenApiCacheKey(domains) {
83
- const input = `2.0.0:${[...domains].sort().join(",")}:3.0.0`;
83
+ const input = `2.1.0-alpha-20260923164312:${[...domains].sort().join(",")}:3.0.0`;
84
84
  return (0, crypto.createHash)("sha256").update(input).digest("hex").slice(0, 8);
85
85
  }
86
86
  /** Returns the server URL to be set in the OpenAPI spec, based on the current namespace. */
@@ -16,10 +16,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
16
16
  const require_rolldown_runtime = require('../../rolldown-runtime-CDQd2xEI.cjs');
17
17
  const require_repository = require('../../repository-CbceYZqc.cjs');
18
18
  const require_router = require('../../router-CxDTb6r1.cjs');
19
+ let _adobe_aio_commerce_lib_core_responses = require("@adobe/aio-commerce-lib-core/responses");
19
20
  let valibot = require("valibot");
20
21
  valibot = require_rolldown_runtime.__toESM(valibot, 1);
21
22
  let _adobe_aio_commerce_lib_core_commerce = require("@adobe/aio-commerce-lib-core/commerce");
22
- let _adobe_aio_commerce_lib_core_responses = require("@adobe/aio-commerce-lib-core/responses");
23
23
 
24
24
  //#region source/actions/association/schema.ts
25
25
  /** Request body for POST / — store association data. */
@@ -18,10 +18,10 @@ const require_schemas = require('../../schemas-3e49M8zz.cjs');
18
18
  const require_environment = require('../../environment-B6533pAY.cjs');
19
19
  const require_router = require('../../router-CxDTb6r1.cjs');
20
20
  let _adobe_aio_commerce_lib_config = require("@adobe/aio-commerce-lib-config");
21
+ let _adobe_aio_commerce_lib_core_responses = require("@adobe/aio-commerce-lib-core/responses");
21
22
  let valibot = require("valibot");
22
23
  valibot = require_rolldown_runtime.__toESM(valibot, 1);
23
24
  let _adobe_aio_commerce_lib_core_commerce = require("@adobe/aio-commerce-lib-core/commerce");
24
- let _adobe_aio_commerce_lib_core_responses = require("@adobe/aio-commerce-lib-core/responses");
25
25
 
26
26
  //#region source/actions/config/schema.ts
27
27
  const AcceptedConfigurationValuesSchema = valibot.union([
@@ -15,15 +15,15 @@
15
15
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
16
16
  const require_rolldown_runtime = require('../../rolldown-runtime-CDQd2xEI.cjs');
17
17
  const require_repository = require('../../repository-CbceYZqc.cjs');
18
+ const require_common = require('../../common-B3KrOG-h.cjs');
19
+ const require_management = require('../../management-DplOGozL.cjs');
18
20
  const require_schemas = require('../../schemas-3e49M8zz.cjs');
19
- const require_validate = require('../../validate-CwWYtRsS.cjs');
20
- const require_common = require('../../common-VSsQEHDv.cjs');
21
- const require_management = require('../../management-Bki3hlxL.cjs');
21
+ const require_validate = require('../../validate-DkmBVWFX.cjs');
22
22
  const require_router = require('../../router-CxDTb6r1.cjs');
23
+ let _adobe_aio_commerce_lib_core_responses = require("@adobe/aio-commerce-lib-core/responses");
23
24
  let valibot = require("valibot");
24
25
  valibot = require_rolldown_runtime.__toESM(valibot, 1);
25
26
  let _adobe_aio_commerce_lib_core_commerce = require("@adobe/aio-commerce-lib-core/commerce");
26
- let _adobe_aio_commerce_lib_core_responses = require("@adobe/aio-commerce-lib-core/responses");
27
27
  let openwhisk = require("openwhisk");
28
28
  openwhisk = require_rolldown_runtime.__toESM(openwhisk, 1);
29
29
 
@@ -15,14 +15,15 @@
15
15
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
16
16
  const require_rolldown_runtime = require('../../rolldown-runtime-CDQd2xEI.cjs');
17
17
  const require_schemas = require('../../schemas-3e49M8zz.cjs');
18
- const require_logging = require('../../logging-Br3xfBNe.cjs');
18
+ const require_constants = require('../../constants-tQUzmimN.cjs');
19
+ const require_logging = require('../../logging-QTsrSwPc.cjs');
19
20
  const require_router = require('../../router-CxDTb6r1.cjs');
20
21
  let _adobe_aio_commerce_lib_api = require("@adobe/aio-commerce-lib-api");
21
22
  let _adobe_aio_commerce_lib_config = require("@adobe/aio-commerce-lib-config");
23
+ let _adobe_aio_commerce_lib_core_responses = require("@adobe/aio-commerce-lib-core/responses");
22
24
  let valibot = require("valibot");
23
25
  valibot = require_rolldown_runtime.__toESM(valibot, 1);
24
26
  let _adobe_aio_commerce_lib_core_commerce = require("@adobe/aio-commerce-lib-core/commerce");
25
- let _adobe_aio_commerce_lib_core_responses = require("@adobe/aio-commerce-lib-core/responses");
26
27
 
27
28
  //#region source/actions/scope-tree/schema.ts
28
29
  const CustomScopeInputSchema = valibot.object({
@@ -104,7 +105,7 @@ router.post("/commerce", {
104
105
  };
105
106
  const commerceConfig = (0, _adobe_aio_commerce_lib_api.resolveCommerceHttpClientParams)(paramsWithCommerceConfig, { tryForwardAuthProvider: true });
106
107
  commerceConfig.fetchOptions ??= {};
107
- commerceConfig.fetchOptions.timeout = require_logging.LIFECYCLE_HTTP_CLIENT_TIMEOUT_MS;
108
+ commerceConfig.fetchOptions.timeout = require_constants.LIFECYCLE_HTTP_CLIENT_TIMEOUT_MS;
108
109
  const result = await (0, _adobe_aio_commerce_lib_config.syncCommerceScopes)(commerceConfig);
109
110
  if (result.error) {
110
111
  logger.error(`Error syncing commerce scopes: ${require_logging.inspect(result.error)}`);
@@ -0,0 +1,447 @@
1
+ /**
2
+ * @license
3
+ *
4
+ * Copyright 2026 Adobe. All rights reserved.
5
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License. You may obtain a copy
7
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software distributed under
10
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
11
+ * OF ANY KIND, either express or implied. See the License for the specific language
12
+ * governing permissions and limitations under the License.
13
+ */
14
+
15
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
16
+ const require_rolldown_runtime = require('../rolldown-runtime-CDQd2xEI.cjs');
17
+ const require_index_node = require('../index.node-De5ENMF8.cjs');
18
+ const require_web_src = require('../web-src-DvGBiJI5.cjs');
19
+ const require_common = require('../common-B3KrOG-h.cjs');
20
+ const require_webhooks = require('../webhooks-zXjrg32x.cjs');
21
+ let _adobe_aio_commerce_lib_core_error = require("@adobe/aio-commerce-lib-core/error");
22
+ let fs = require("fs");
23
+ let path = require("path");
24
+ path = require_rolldown_runtime.__toESM(path, 1);
25
+ let consola = require("consola");
26
+ consola = require_rolldown_runtime.__toESM(consola, 1);
27
+ let _adobe_aio_lib_ims = require("@adobe/aio-lib-ims");
28
+ _adobe_aio_lib_ims = require_rolldown_runtime.__toESM(_adobe_aio_lib_ims, 1);
29
+ let _adobe_aio_lib_core_config = require("@adobe/aio-lib-core-config");
30
+ _adobe_aio_lib_core_config = require_rolldown_runtime.__toESM(_adobe_aio_lib_core_config, 1);
31
+ let consola_utils = require("consola/utils");
32
+ let ky = require("ky");
33
+ ky = require_rolldown_runtime.__toESM(ky, 1);
34
+ let valibot = require("valibot");
35
+ valibot = require_rolldown_runtime.__toESM(valibot, 1);
36
+ let timers_promises = require("timers/promises");
37
+ let dotenv = require("dotenv");
38
+ dotenv = require_rolldown_runtime.__toESM(dotenv, 1);
39
+
40
+ //#region ../../packages-private/scripting-utils/source/aio/auth.ts
41
+ const { context: context$1, getToken } = _adobe_aio_lib_ims.default;
42
+ /** Gets an IMS access token for the current CLI IMS context. */
43
+ async function getUserToken() {
44
+ const contextName = await context$1.getCurrent() ?? "cli";
45
+ return getToken(contextName, {});
46
+ }
47
+
48
+ //#endregion
49
+ //#region ../../packages-private/scripting-utils/source/aio/context.ts
50
+ /**
51
+ * Reads the current App Builder project and Runtime namespace from the local AIO CLI config.
52
+ * @throws If either the project or the runtime namespace is not configured.
53
+ */
54
+ function getAioProjectContext() {
55
+ const project = _adobe_aio_lib_core_config.default.get("project");
56
+ const namespace = _adobe_aio_lib_core_config.default.get("runtime.namespace");
57
+ if (!(project && namespace)) throw new Error("The current App Builder project and Runtime namespace are required");
58
+ return {
59
+ namespace,
60
+ project
61
+ };
62
+ }
63
+ /** Reads the configured AIO CLI environment, defaulting to `"prod"`. */
64
+ function getAioCliEnv() {
65
+ return _adobe_aio_lib_core_config.default.get("cli.env") === "stage" ? "stage" : "prod";
66
+ }
67
+
68
+ //#endregion
69
+ //#region source/commands/hooks/post-app-deploy/polling.ts
70
+ const POLL_INTERVAL_MS = 1e3;
71
+ const UpgradeStateSchema = valibot.object({
72
+ failure: valibot.optional(valibot.object({
73
+ key: valibot.string(),
74
+ message: valibot.optional(valibot.string())
75
+ })),
76
+ id: valibot.string(),
77
+ status: valibot.picklist([
78
+ "pending",
79
+ "in-progress",
80
+ "succeeded",
81
+ "failed"
82
+ ])
83
+ });
84
+ /** Reads the latest upgrade state from the installation action. */
85
+ async function getUpgradeState(request) {
86
+ try {
87
+ const response = await ky.default.get(request.endpoint, { headers: request.headers });
88
+ if (response.status === 204) return null;
89
+ const parsed = valibot.safeParse(UpgradeStateSchema, await response.json());
90
+ return parsed.success ? parsed.output : null;
91
+ } catch (error) {
92
+ consola.consola.debug("Unable to read upgrade status; stopping upgrade polling.", { error });
93
+ return null;
94
+ }
95
+ }
96
+ /** Waits for an automatic upgrade when its status remains available. */
97
+ async function waitForAutomaticUpgrade(request) {
98
+ const state = await getUpgradeState(request);
99
+ if (!state) return;
100
+ if (state.status === "succeeded") {
101
+ consola.consola.success("App upgrade completed.\n");
102
+ return;
103
+ }
104
+ if (state.status === "failed") {
105
+ const reason = state.failure?.message ?? state.failure?.key ?? "The lifecycle attempt failed";
106
+ throw new Error(`App upgrade failed: ${reason}`);
107
+ }
108
+ consola.consola.start("App upgrade is in progress...");
109
+ await (0, timers_promises.setTimeout)(POLL_INTERVAL_MS);
110
+ return waitForAutomaticUpgrade(request);
111
+ }
112
+
113
+ //#endregion
114
+ //#region source/commands/hooks/post-app-deploy/main.ts
115
+ /** Returns true for a no-op reason defined by the upgrade API contract. */
116
+ function isSkippedReason(reason) {
117
+ return reason === "already-current" || reason === "not-associated" || reason === "not-installed";
118
+ }
119
+ /** Returns true if the result indicates that the upgrade was skipped. */
120
+ function isSkippedResult(result) {
121
+ return "skipped" in result;
122
+ }
123
+ /** Invokes the upgrade action. */
124
+ async function createUpgradeRequest() {
125
+ const { project, namespace } = getAioProjectContext();
126
+ const token = await getUserToken();
127
+ const endpoint = `https://${namespace}.adobeioruntime.net/api/v1/web/app-management/installation`;
128
+ const ioEventsEnv = getAioCliEnv();
129
+ const ioEventsUrl = ioEventsEnv === "stage" ? "https://events-stage.adobe.io" : "https://events.adobe.io";
130
+ return {
131
+ body: {
132
+ appData: {
133
+ consumerOrgId: project.org.id,
134
+ orgName: project.org.name,
135
+ projectId: project.id,
136
+ projectName: project.name,
137
+ projectTitle: project.title,
138
+ workspaceId: project.workspace.id,
139
+ workspaceName: project.workspace.name,
140
+ workspaceTitle: project.workspace.title
141
+ },
142
+ ioEventsEnv,
143
+ ioEventsUrl
144
+ },
145
+ endpoint,
146
+ headers: {
147
+ Authorization: `Bearer ${token}`,
148
+ [require_common.INSTALLATION_INVOCATION_SOURCE_HEADER]: require_common.POST_APP_DEPLOY_INVOCATION_SOURCE,
149
+ "x-gw-ims-org-id": project.org.ims_org_id
150
+ }
151
+ };
152
+ }
153
+ /** Invokes the upgrade action. */
154
+ async function invokeAction(request) {
155
+ consola.consola.debug(`Upgrade endpoint: ${request.endpoint}`);
156
+ try {
157
+ return await ky.default.post(request.endpoint, {
158
+ headers: request.headers,
159
+ json: request.body
160
+ }).json();
161
+ } catch (error) {
162
+ if (error instanceof ky.HTTPError) {
163
+ const details = await error.response.json();
164
+ if (error.response.status === 409 && isSkippedReason(details.reason)) return {
165
+ reason: details.reason,
166
+ skipped: true
167
+ };
168
+ throw new Error(`Failed to trigger app upgrade (HTTP ${error.response.status}): ${JSON.stringify(details, null, 2)}`, { cause: error });
169
+ }
170
+ throw error;
171
+ }
172
+ }
173
+ /** Invokes the deployed app's upgrade endpoint. */
174
+ async function run$3() {
175
+ const { upgradeMode } = (await require_index_node.parseCommerceAppConfig()).metadata;
176
+ consola.consola.log("");
177
+ consola.consola.start("Checking for app upgrades...");
178
+ const request = await createUpgradeRequest();
179
+ const result = await invokeAction(request);
180
+ if (isSkippedResult(result)) {
181
+ consola.consola.info(`No upgrade was run: ${result.reason}.\n`);
182
+ return result;
183
+ }
184
+ if (upgradeMode === "manual") consola.consola.success(`You have set ${consola_utils.colors.cyan("metadata.upgradeMode")} to ${consola_utils.colors.cyan("manual")}. The upgrade plan has been created but will not be executed.`);
185
+ else consola.consola.success(`You have set ${consola_utils.colors.cyan("metadata.upgradeMode")} to ${consola_utils.colors.cyan("auto")}. The upgrade plan has been created. Execution will begin shortly.`);
186
+ consola.consola.box(["Upgrade plan", JSON.stringify(result.plan, null, 2)].join("\n\n"));
187
+ if (upgradeMode === "auto") await waitForAutomaticUpgrade(request);
188
+ return result;
189
+ }
190
+
191
+ //#endregion
192
+ //#region ../../packages-private/scripting-utils/source/env.ts
193
+ /**
194
+ * This module exports shared environment utilities for the AIO Commerce SDK.
195
+ * @packageDocumentation
196
+ */
197
+ const { context } = _adobe_aio_lib_ims.default;
198
+ const IMS_KEYS = {
199
+ client_id: "AIO_COMMERCE_AUTH_IMS_CLIENT_ID",
200
+ client_secrets: "AIO_COMMERCE_AUTH_IMS_CLIENT_SECRETS",
201
+ ims_org_id: "AIO_COMMERCE_AUTH_IMS_ORG_ID",
202
+ scopes: "AIO_COMMERCE_AUTH_IMS_SCOPES",
203
+ technical_account_email: "AIO_COMMERCE_AUTH_IMS_TECHNICAL_ACCOUNT_EMAIL",
204
+ technical_account_id: "AIO_COMMERCE_AUTH_IMS_TECHNICAL_ACCOUNT_ID"
205
+ };
206
+ /**
207
+ * Replaces or creates an environment variable in a .env file and sets it in the
208
+ * current process.
209
+ * @param filePath - The path to the .env file
210
+ * @param key - The environment variable key to replace or create
211
+ * @param value - The new value for the environment variable
212
+ */
213
+ function replaceEnvVar(filePath, key, value) {
214
+ const envPath = path.default.resolve(filePath);
215
+ const envLines = (0, fs.readFileSync)(envPath, "utf8").split("\n");
216
+ const formattedValue = value.includes(" ") ? `"${value}"` : value;
217
+ let keyExists = false;
218
+ const updatedLines = envLines.map((line) => {
219
+ if (line.trim().startsWith("#") || !line.includes("=")) return line;
220
+ const [currentKey] = line.split("=");
221
+ if (currentKey === key) {
222
+ keyExists = true;
223
+ return `${key}=${formattedValue}`;
224
+ }
225
+ return line;
226
+ });
227
+ if (!keyExists) updatedLines.push(`${key}=${formattedValue}`);
228
+ (0, fs.writeFileSync)(envPath, updatedLines.join("\n"), "utf8");
229
+ process.env[key] = value;
230
+ }
231
+ /**
232
+ * Sets the `NODE_ENV` environment variable in the current process and in the app
233
+ * `.env` file, so the web bundler (Parcel) ships the matching React build.
234
+ * Creates the `.env` if absent.
235
+ * @param mode - The environment mode to set in `NODE_ENV`.
236
+ * @param projectRoot - Resolved project root containing the `.env` file.
237
+ */
238
+ function setNodeEnv(mode, projectRoot) {
239
+ const envPath = path.default.join(projectRoot, ".env");
240
+ if (!(0, fs.existsSync)(envPath)) (0, fs.writeFileSync)(envPath, "", "utf8");
241
+ replaceEnvVar(envPath, "NODE_ENV", mode);
242
+ }
243
+ /** Resolves the IMS server to server context from the project workspace credentials. */
244
+ function resolveImsS2SContext() {
245
+ const [credential] = (_adobe_aio_lib_core_config.default.get("project.workspace.details.credentials") ?? []).filter(({ integration_type }) => integration_type === "oauth_server_to_server").map(({ name }) => name);
246
+ if (!credential) return Promise.resolve(null);
247
+ return context.get(credential);
248
+ }
249
+ /**
250
+ * Syncs the IMS credentials environment variables from the configured IMS context in
251
+ * the .env file, in a way that is compatible with `@adobe/aio-commerce-lib-auth`.
252
+ * @param projectRoot - Resolved project root containing the `.env` file.
253
+ */
254
+ async function syncImsCredentials(projectRoot) {
255
+ const envPath = path.default.join(projectRoot, ".env");
256
+ if (!(0, fs.existsSync)(envPath)) return {
257
+ ok: false,
258
+ reason: "missing-env"
259
+ };
260
+ const envVars = dotenv.default.parse((0, fs.readFileSync)(envPath, "utf8"));
261
+ const imsContext = await resolveImsS2SContext();
262
+ if (!imsContext) return {
263
+ ok: false,
264
+ reason: "no-ims-context"
265
+ };
266
+ const { data } = imsContext;
267
+ for (const [key, value] of Object.entries(data)) {
268
+ const oauthKey = IMS_KEYS[key];
269
+ if (!oauthKey) continue;
270
+ if (!envVars[oauthKey] || envVars[oauthKey] !== value) replaceEnvVar(envPath, oauthKey, value);
271
+ }
272
+ return { ok: true };
273
+ }
274
+
275
+ //#endregion
276
+ //#region source/commands/hooks/pre-app-build.ts
277
+ /**
278
+ * Runs the pre-app-build hook for the given extension.
279
+ * @param extension - The extension to run the hook for.
280
+ * @param projectRoot - Resolved project root containing extension files.
281
+ * @param templatesDir - Directory containing action templates.
282
+ * @param options - Hook options.
283
+ * @param options.isDevSession - Whether the build runs within `aio app run` or `aio app dev`, which keeps `NODE_ENV` untouched.
284
+ */
285
+ async function run$2(extension, projectRoot, templatesDir = require_web_src.TEMPLATES_DIR, { isDevSession = false } = {}) {
286
+ const appManifest = await require_web_src.loadAppManifest(projectRoot);
287
+ await require_web_src.prepareRuntimeAppConfigModule(appManifest, projectRoot);
288
+ if (extension === "extensibility/1") {
289
+ const { doc: extensibilityExtConfig } = await require_web_src.readExtConfig(require_web_src.EXTENSIBILITY_EXTENSION_POINT_ID, projectRoot);
290
+ await require_web_src.run$1(appManifest, projectRoot);
291
+ await require_web_src.generateActionFiles(appManifest, require_web_src.getRuntimeActions(extensibilityExtConfig.toJS(), "app-management"), require_web_src.EXTENSIBILITY_EXTENSION_POINT_ID, templatesDir, projectRoot);
292
+ consola.default.info("Syncing IMS credentials...");
293
+ await syncImsCredentials(projectRoot);
294
+ return;
295
+ }
296
+ if (extension === "configuration/1") {
297
+ const { doc: businessConfigExtConfig } = await require_web_src.readExtConfig(require_web_src.CONFIGURATION_EXTENSION_POINT_ID, projectRoot);
298
+ await require_web_src.run(appManifest, projectRoot);
299
+ await require_web_src.generateActionFiles(appManifest, require_web_src.getRuntimeActions(businessConfigExtConfig.toJS(), "business-configuration"), require_web_src.CONFIGURATION_EXTENSION_POINT_ID, templatesDir, projectRoot);
300
+ return;
301
+ }
302
+ if (extension === "backend-ui/2") {
303
+ if (require_webhooks.hasBackendUiV2Components(appManifest)) {
304
+ const extConfig = await require_web_src.updateExtConfig(appManifest, require_web_src.BACKEND_UI_V2_EXTENSION_POINT_ID, projectRoot);
305
+ if (extConfig.operations?.view) {
306
+ await require_web_src.prepareWebSourceImportAlias(extConfig, projectRoot);
307
+ await require_web_src.generateWebSrc(extConfig, appManifest.metadata.displayName, projectRoot, templatesDir);
308
+ if (!isDevSession) await setNodeEnv("production", projectRoot);
309
+ }
310
+ }
311
+ return;
312
+ }
313
+ throw new Error(`Unsupported extension: ${extension}`);
314
+ }
315
+
316
+ //#endregion
317
+ //#region source/commands/hooks/pre-app-dev.ts
318
+ /**
319
+ * Resets the web build back to development by setting `NODE_ENV` in the process and the project `.env`.
320
+ * @param projectRoot - Resolved project root containing the `.env` file.
321
+ */
322
+ async function run$1(projectRoot) {
323
+ await setNodeEnv("development", projectRoot);
324
+ }
325
+
326
+ //#endregion
327
+ //#region source/commands/hooks/pre-app-run.ts
328
+ /**
329
+ * Resets the web build back to development by setting `NODE_ENV` in the process and the project `.env`.
330
+ * @param projectRoot - Resolved project root containing the `.env` file.
331
+ */
332
+ async function run(projectRoot) {
333
+ await setNodeEnv("development", projectRoot);
334
+ }
335
+
336
+ //#endregion
337
+ //#region source/cli/index.ts
338
+ /**
339
+ * Internal App Builder hook handlers, loaded by the hook files that
340
+ * `@adobe/aio-commerce-lib-app` generates. Not part of the public API.
341
+ * @packageDocumentation
342
+ */
343
+ const USER_HOOKS_DIR = "hooks";
344
+ const USER_HOOK_FILE_EXTENSIONS = [
345
+ ".ts",
346
+ ".mts",
347
+ ".cts",
348
+ ".js",
349
+ ".mjs",
350
+ ".cjs"
351
+ ];
352
+ let isDevSession = false;
353
+ /**
354
+ * Finds the user hook file for a hook, looking in the extension point's `hooks`
355
+ * folder first and then in the project root `hooks` folder.
356
+ *
357
+ * @param projectRoot - Resolved project root.
358
+ * @param extensionPointId - The extension point ID, e.g. "commerce/backend-ui/2".
359
+ * @param hookName - The hook name, e.g. "pre-app-build".
360
+ */
361
+ function findUserHook(projectRoot, extensionPointId, hookName) {
362
+ const dirs = [(0, path.join)(projectRoot, require_web_src.getExtensionPointFolderPath(extensionPointId), USER_HOOKS_DIR), (0, path.join)(projectRoot, USER_HOOKS_DIR)];
363
+ for (const dir of dirs) {
364
+ const matches = USER_HOOK_FILE_EXTENSIONS.map((extension) => (0, path.join)(dir, `${hookName}${extension}`)).filter((file) => (0, fs.existsSync)(file));
365
+ if (matches.length > 1) throw new Error(`Found more than one "${hookName}" hook file in ${dir}: ${matches.join(", ")}. Keep only one.`);
366
+ if (matches.length === 1) return matches[0];
367
+ }
368
+ return null;
369
+ }
370
+ /**
371
+ * Runs the user hook file for a hook, if there is one.
372
+ *
373
+ * @param projectRoot - Resolved project root.
374
+ * @param hookName - The hook name, e.g. "pre-app-build".
375
+ * @param extension - The extension the hook is registered for.
376
+ * @param hookArgs - The argument the aio CLI passed to the hook.
377
+ */
378
+ async function runUserHook(projectRoot, hookName, extension, hookArgs) {
379
+ const extensionPoint = `commerce/${extension}`;
380
+ const file = findUserHook(projectRoot, extensionPoint, hookName);
381
+ if (!file) return;
382
+ const { createJiti } = await import("jiti");
383
+ const hook = await createJiti(require("url").pathToFileURL(__filename).href).import(file, { default: true });
384
+ if (typeof hook !== "function") throw new Error(`${file} must export a function as its default export.`);
385
+ await hook(hookArgs, { extensionPoint });
386
+ }
387
+ /**
388
+ * Creates an async App Builder hook that runs the given function and then the
389
+ * user hook file, logging any error and exiting the process with code 1.
390
+ *
391
+ * @param hookName - The hook name, e.g. "pre-app-build".
392
+ * @param extension - The extension the hook is registered for.
393
+ * @param fn - The hook implementation.
394
+ */
395
+ function createHook(hookName, extension, fn) {
396
+ return async (hookArgs) => {
397
+ try {
398
+ const projectRoot = await require_index_node.getProjectRootDirectory();
399
+ await fn(projectRoot);
400
+ await runUserHook(projectRoot, hookName, extension, hookArgs);
401
+ } catch (error) {
402
+ if (error instanceof _adobe_aio_commerce_lib_core_error.CommerceSdkValidationError) consola.default.error(error.display());
403
+ else consola.default.error(error);
404
+ process.exit(1);
405
+ }
406
+ };
407
+ }
408
+ /**
409
+ * Creates the `pre-app-build` hook for the given extension.
410
+ * @param extension - The extension the hook is registered for.
411
+ */
412
+ function preAppBuild(extension) {
413
+ return createHook("pre-app-build", extension, (projectRoot) => run$2(extension, projectRoot, require_web_src.TEMPLATES_DIR, { isDevSession }));
414
+ }
415
+ /**
416
+ * Creates the `pre-app-run` hook for the given extension.
417
+ * @param extension - The extension the hook is registered for.
418
+ */
419
+ function preAppRun(extension) {
420
+ return createHook("pre-app-run", extension, (projectRoot) => {
421
+ isDevSession = true;
422
+ return run(projectRoot);
423
+ });
424
+ }
425
+ /**
426
+ * Creates the `pre-app-dev` hook for the given extension.
427
+ * @param extension - The extension the hook is registered for.
428
+ */
429
+ function preAppDev(extension) {
430
+ return createHook("pre-app-dev", extension, (projectRoot) => {
431
+ isDevSession = true;
432
+ return run$1(projectRoot);
433
+ });
434
+ }
435
+ /**
436
+ * Creates the `post-app-deploy` hook for the given extension.
437
+ * @param extension - The extension the hook is registered for.
438
+ */
439
+ function postAppDeploy(extension) {
440
+ return createHook("post-app-deploy", extension, () => run$3());
441
+ }
442
+
443
+ //#endregion
444
+ exports.postAppDeploy = postAppDeploy;
445
+ exports.preAppBuild = preAppBuild;
446
+ exports.preAppDev = preAppDev;
447
+ exports.preAppRun = preAppRun;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @license
3
+ *
4
+ * Copyright 2026 Adobe. All rights reserved.
5
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License. You may obtain a copy
7
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software distributed under
10
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
11
+ * OF ANY KIND, either express or implied. See the License for the specific language
12
+ * governing permissions and limitations under the License.
13
+ */
14
+
15
+ //#region source/commands/hooks/pre-app-build.d.ts
16
+ /** The extensions that register a `pre-app-build` hook. */
17
+ type Extension = "extensibility/1" | "configuration/1" | "backend-ui/2";
18
+ //#endregion
19
+ //#region source/cli/index.d.ts
20
+ /**
21
+ * Creates the `pre-app-build` hook for the given extension.
22
+ * @param extension - The extension the hook is registered for.
23
+ */
24
+ export declare function preAppBuild(extension: Extension): (hookArgs?: unknown) => Promise<void>;
25
+ /**
26
+ * Creates the `pre-app-run` hook for the given extension.
27
+ * @param extension - The extension the hook is registered for.
28
+ */
29
+ export declare function preAppRun(extension: Extension): (hookArgs?: unknown) => Promise<void>;
30
+ /**
31
+ * Creates the `pre-app-dev` hook for the given extension.
32
+ * @param extension - The extension the hook is registered for.
33
+ */
34
+ export declare function preAppDev(extension: Extension): (hookArgs?: unknown) => Promise<void>;
35
+ /**
36
+ * Creates the `post-app-deploy` hook for the given extension.
37
+ * @param extension - The extension the hook is registered for.
38
+ */
39
+ export declare function postAppDeploy(extension: Extension): (hookArgs?: unknown) => Promise<void>;
40
+ //#endregion