@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.
- package/CHANGELOG.md +10 -0
- package/README.md +4 -0
- package/dist/cjs/actions/app-config/index.cjs +3 -3
- package/dist/cjs/actions/association/index.cjs +1 -1
- package/dist/cjs/actions/config/index.cjs +1 -1
- package/dist/cjs/actions/installation/index.cjs +4 -4
- package/dist/cjs/actions/scope-tree/index.cjs +4 -3
- package/dist/cjs/cli/index.cjs +447 -0
- package/dist/cjs/cli/index.d.cts +40 -0
- package/dist/cjs/commands/index.cjs +73 -1717
- package/dist/cjs/{common-VSsQEHDv.cjs → common-B3KrOG-h.cjs} +1 -1
- package/dist/cjs/config/index.node.cjs +3 -3
- package/dist/{es/logging-CXesop3u.mjs → cjs/constants-tQUzmimN.cjs} +6 -18
- package/dist/cjs/{index.node-vcOo1rt0.cjs → index.node-De5ENMF8.cjs} +2 -2
- package/dist/cjs/{logging-Br3xfBNe.cjs → logging-QTsrSwPc.cjs} +0 -16
- package/dist/cjs/management/index.cjs +1 -1
- package/dist/cjs/{management-Bki3hlxL.cjs → management-DplOGozL.cjs} +11 -10
- package/dist/cjs/{validate-CwWYtRsS.cjs → validate-DkmBVWFX.cjs} +1 -1
- package/dist/cjs/web-src-DvGBiJI5.cjs +1521 -0
- package/dist/cjs/{webhooks-Bcq2Qy7q.cjs → webhooks-zXjrg32x.cjs} +57 -57
- package/dist/es/actions/app-config/index.mjs +3 -3
- package/dist/es/actions/association/index.mjs +1 -1
- package/dist/es/actions/config/index.mjs +1 -1
- package/dist/es/actions/installation/index.mjs +4 -4
- package/dist/es/actions/scope-tree/index.mjs +3 -2
- package/dist/es/cli/index.d.mts +40 -0
- package/dist/es/cli/index.mjs +435 -0
- package/dist/es/commands/index.mjs +29 -1666
- package/dist/es/{common-dy6NrZt8.mjs → common-BWUDGasu.mjs} +1 -1
- package/dist/es/config/index.node.mjs +3 -3
- package/dist/es/constants-CSQsZaDP.mjs +25 -0
- package/dist/es/{index.node-CW46zuxW.mjs → index.node-C5D5IzSs.mjs} +2 -2
- package/dist/es/logging-DbJHXSKh.mjs +32 -0
- package/dist/es/management/index.mjs +1 -1
- package/dist/es/{management-DgwAhaaJ.mjs → management-YDkb15SJ.mjs} +6 -5
- package/dist/es/{validate-NzW1FQwL.mjs → validate-Pd7RIA_3.mjs} +1 -1
- package/dist/es/web-src-CLEUvMl7.mjs +1345 -0
- package/dist/es/{webhooks-CHZ1SXxw.mjs → webhooks-BMBfTqwi.mjs} +58 -58
- package/package.json +11 -1
- /package/dist/cjs/{commands/templates → templates}/admin-ui/tsconfig.json +0 -0
- /package/dist/cjs/{commands/templates → templates}/admin-ui/web-src/.babelrc +0 -0
- /package/dist/cjs/{commands/templates → templates}/admin-ui/web-src/index.css +0 -0
- /package/dist/cjs/{commands/templates → templates}/admin-ui/web-src/index.html +0 -0
- /package/dist/cjs/{commands/templates → templates}/admin-ui/web-src/src/app.jsx +0 -0
- /package/dist/cjs/{commands/templates → templates}/admin-ui/web-src/src/components/welcome.jsx +0 -0
- /package/dist/cjs/{commands/templates → templates}/admin-ui/web-src/src/pages/main-page.jsx +0 -0
- /package/dist/cjs/{commands/templates → templates}/admin-ui/web-src-template.d.ts +0 -0
- /package/dist/cjs/{commands/templates → templates}/app-management/app-config.js.template +0 -0
- /package/dist/cjs/{commands/templates → templates}/app-management/association.js.template +0 -0
- /package/dist/cjs/{commands/templates → templates}/app-management/custom-scripts.js.template +0 -0
- /package/dist/cjs/{commands/templates → templates}/app-management/installation.js.template +0 -0
- /package/dist/cjs/{commands/templates → templates}/business-configuration/config.js.template +0 -0
- /package/dist/cjs/{commands/templates → templates}/business-configuration/scope-tree.js.template +0 -0
- /package/dist/cjs/{commands/templates → templates}/typescript/webpack-config.cjs +0 -0
- /package/dist/es/{commands/templates → templates}/admin-ui/tsconfig.json +0 -0
- /package/dist/es/{commands/templates → templates}/admin-ui/web-src/.babelrc +0 -0
- /package/dist/es/{commands/templates → templates}/admin-ui/web-src/index.css +0 -0
- /package/dist/es/{commands/templates → templates}/admin-ui/web-src/index.html +0 -0
- /package/dist/es/{commands/templates → templates}/admin-ui/web-src/src/app.jsx +0 -0
- /package/dist/es/{commands/templates → templates}/admin-ui/web-src/src/components/welcome.jsx +0 -0
- /package/dist/es/{commands/templates → templates}/admin-ui/web-src/src/pages/main-page.jsx +0 -0
- /package/dist/es/{commands/templates → templates}/admin-ui/web-src-template.d.ts +0 -0
- /package/dist/es/{commands/templates → templates}/app-management/app-config.js.template +0 -0
- /package/dist/es/{commands/templates → templates}/app-management/association.js.template +0 -0
- /package/dist/es/{commands/templates → templates}/app-management/custom-scripts.js.template +0 -0
- /package/dist/es/{commands/templates → templates}/app-management/installation.js.template +0 -0
- /package/dist/es/{commands/templates → templates}/business-configuration/config.js.template +0 -0
- /package/dist/es/{commands/templates → templates}/business-configuration/scope-tree.js.template +0 -0
- /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-
|
|
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.
|
|
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-
|
|
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
|
|
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 =
|
|
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
|