@adobe/aio-commerce-lib-app 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/dist/cjs/actions/app-config.cjs +1 -1
- package/dist/cjs/actions/app-config.d.cts +3 -3
- package/dist/cjs/actions/config.cjs +33 -2
- package/dist/cjs/actions/config.d.cts +2 -2
- package/dist/cjs/actions/installation.cjs +167 -43
- package/dist/cjs/actions/installation.d.cts +4 -4
- package/dist/cjs/actions/scope-tree.d.cts +3 -3
- package/dist/cjs/{app-lymFcs59.d.cts → app-DcQMhW2N.d.cts} +13 -1
- package/dist/cjs/commands/index.cjs +3 -3
- package/dist/cjs/config/index.cjs +3 -3
- package/dist/cjs/config/index.d.cts +39 -3
- package/dist/cjs/{config-YEeaEqzi.cjs → config-BppBKCFj.cjs} +1 -1
- package/dist/{es/index-D33OCH0D.d.mts → cjs/index-BVwQk9bx.d.cts} +103 -34
- package/dist/cjs/management/index.cjs +3 -1
- package/dist/cjs/management/index.d.cts +2 -2
- package/dist/cjs/{management-PZtLe4Ji.cjs → management-C6xG5bfl.cjs} +731 -163
- package/dist/cjs/{validate-CwwYD8aC.cjs → validate-CeUCT_7k.cjs} +7 -3
- package/dist/cjs/{webhooks-CbZpv9y_.cjs → webhooks-CLtDxwMa.cjs} +33 -0
- package/dist/es/actions/app-config.d.mts +3 -3
- package/dist/es/actions/app-config.mjs +1 -1
- package/dist/es/actions/config.d.mts +2 -2
- package/dist/es/actions/config.mjs +34 -3
- package/dist/es/actions/installation.d.mts +4 -4
- package/dist/es/actions/installation.mjs +168 -44
- package/dist/es/actions/scope-tree.d.mts +3 -3
- package/dist/es/actions/scope-tree.mjs +1 -1
- package/dist/es/{app-Ct7Y0NP8.d.mts → app-DJr-mN9d.d.mts} +13 -1
- package/dist/es/commands/index.mjs +3 -3
- package/dist/es/config/index.d.mts +39 -3
- package/dist/es/config/index.mjs +3 -3
- package/dist/es/{config-BbrkH0Xt.mjs → config-BohwKkQS.mjs} +1 -1
- package/dist/{cjs/index-DRhLtRrX.d.cts → es/index-BENO5T7n.d.mts} +103 -34
- package/dist/es/management/index.d.mts +2 -2
- package/dist/es/management/index.mjs +2 -2
- package/dist/es/{management-CIoVWirU.mjs → management-ByHvVJ12.mjs} +723 -167
- package/dist/es/{validate-qRpfubPo.mjs → validate-CqJdGzyZ.mjs} +8 -4
- package/dist/es/{webhooks-NgM6k3_r.mjs → webhooks-CYo-pqbR.mjs} +23 -2
- package/package.json +5 -4
- /package/dist/es/{schemas-BvPxQwgQ.mjs → schemas-CVXHgUhv.mjs} +0 -0
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
const require_schemas = require('./schemas-nkIxa8sL.cjs');
|
|
16
|
-
const require_webhooks = require('./webhooks-
|
|
16
|
+
const require_webhooks = require('./webhooks-CLtDxwMa.cjs');
|
|
17
17
|
let _adobe_aio_commerce_lib_core_error = require("@adobe/aio-commerce-lib-core/error");
|
|
18
18
|
let valibot = require("valibot");
|
|
19
19
|
valibot = require_schemas.__toESM(valibot);
|
|
@@ -37,6 +37,7 @@ function hasBusinessConfigSchema(config) {
|
|
|
37
37
|
|
|
38
38
|
//#endregion
|
|
39
39
|
//#region source/config/schema/metadata.ts
|
|
40
|
+
const MAX_ID_LENGTH = 100;
|
|
40
41
|
const MAX_DESCRIPTION_LENGTH = 255;
|
|
41
42
|
const MAX_DISPLAY_NAME_LENGTH = 50;
|
|
42
43
|
const NUMERIC_IDENTIFIER = "(0|[1-9]\\d*)";
|
|
@@ -46,7 +47,7 @@ function nonEmptyString(fieldName) {
|
|
|
46
47
|
}
|
|
47
48
|
/** The schema for the metadata of the application. */
|
|
48
49
|
const MetadataSchema = valibot.object({
|
|
49
|
-
id: require_schemas.alphaNumericOrHyphenSchema("application id (metadata.id)"),
|
|
50
|
+
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`)),
|
|
50
51
|
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`)),
|
|
51
52
|
description: valibot.pipe(nonEmptyString("metadata description"), valibot.maxLength(MAX_DESCRIPTION_LENGTH, `The metadata description must not be longer than ${MAX_DESCRIPTION_LENGTH} characters`)),
|
|
52
53
|
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')"))
|
|
@@ -67,6 +68,7 @@ const CommerceAppConfigSchema = valibot.looseObject({
|
|
|
67
68
|
metadata: MetadataSchema,
|
|
68
69
|
businessConfig: valibot.optional(_adobe_aio_commerce_lib_config.SchemaBusinessConfig),
|
|
69
70
|
eventing: valibot.optional(require_webhooks.EventingSchema),
|
|
71
|
+
adminUiSdk: valibot.optional(require_webhooks.AdminUiSdkSchema),
|
|
70
72
|
installation: valibot.optional(require_webhooks.InstallationSchema),
|
|
71
73
|
webhooks: valibot.optional(require_webhooks.WebhooksSchema)
|
|
72
74
|
});
|
|
@@ -83,7 +85,8 @@ const CommerceAppConfigSchemas = {
|
|
|
83
85
|
"businessConfig.schema": valibot.unwrap(_adobe_aio_commerce_lib_config.SchemaBusinessConfig.entries.schema),
|
|
84
86
|
"eventing.commerce": valibot.unwrap(require_webhooks.EventingSchema.entries.commerce),
|
|
85
87
|
"eventing.external": valibot.unwrap(require_webhooks.EventingSchema.entries.external),
|
|
86
|
-
"installation.customInstallationSteps": valibot.unwrap(require_webhooks.InstallationSchema.entries.customInstallationSteps)
|
|
88
|
+
"installation.customInstallationSteps": valibot.unwrap(require_webhooks.InstallationSchema.entries.customInstallationSteps),
|
|
89
|
+
adminUiSdk: require_webhooks.AdminUiSdkSchema
|
|
87
90
|
};
|
|
88
91
|
/**
|
|
89
92
|
* Get the config domains that are present in the config.
|
|
@@ -98,6 +101,7 @@ function getConfigDomains(config) {
|
|
|
98
101
|
eventing: withCommerceEvents || withExternalEvents,
|
|
99
102
|
installation: require_webhooks.hasCustomInstallation(config),
|
|
100
103
|
webhooks: require_webhooks.hasWebhooks(config),
|
|
104
|
+
adminUiSdk: require_webhooks.hasAdminUiSdk(config),
|
|
101
105
|
"businessConfig.schema": hasBusinessConfigSchema(config),
|
|
102
106
|
"eventing.commerce": withCommerceEvents,
|
|
103
107
|
"eventing.external": withExternalEvents,
|
|
@@ -16,6 +16,27 @@ const require_schemas = require('./schemas-nkIxa8sL.cjs');
|
|
|
16
16
|
let valibot = require("valibot");
|
|
17
17
|
valibot = require_schemas.__toESM(valibot);
|
|
18
18
|
|
|
19
|
+
//#region source/config/schema/admin-ui-sdk.ts
|
|
20
|
+
/**
|
|
21
|
+
* Schema for the Admin UI SDK registration parameters (for the `adminUiSdk.registration` config section).
|
|
22
|
+
* @see https://developer.adobe.com/commerce/extensibility/admin-ui-sdk/extension-points/ for more details.
|
|
23
|
+
*/
|
|
24
|
+
const AdminUiSdkRegistrationSchema = valibot.object({ menuItems: valibot.array(valibot.object({
|
|
25
|
+
id: valibot.string(),
|
|
26
|
+
title: valibot.optional(valibot.string()),
|
|
27
|
+
parent: valibot.optional(valibot.string()),
|
|
28
|
+
sortOrder: valibot.optional(valibot.number()),
|
|
29
|
+
sandbox: valibot.optional(valibot.string()),
|
|
30
|
+
isSection: valibot.optional(valibot.boolean())
|
|
31
|
+
})) });
|
|
32
|
+
/** Schema for Admin UI SDK configuration. */
|
|
33
|
+
const AdminUiSdkSchema = valibot.object({ registration: AdminUiSdkRegistrationSchema });
|
|
34
|
+
/** Check if config has Admin UI SDK registration configuration. */
|
|
35
|
+
function hasAdminUiSdk(config) {
|
|
36
|
+
return config.adminUiSdk !== void 0 && config.adminUiSdk.registration !== void 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
//#endregion
|
|
19
40
|
//#region source/config/schema/eventing.ts
|
|
20
41
|
const MAX_DESCRIPTION_LENGTH$1 = 255;
|
|
21
42
|
const MAX_LABEL_LENGTH = 100;
|
|
@@ -291,6 +312,12 @@ function hasWebhooks(config) {
|
|
|
291
312
|
}
|
|
292
313
|
|
|
293
314
|
//#endregion
|
|
315
|
+
Object.defineProperty(exports, 'AdminUiSdkSchema', {
|
|
316
|
+
enumerable: true,
|
|
317
|
+
get: function () {
|
|
318
|
+
return AdminUiSdkSchema;
|
|
319
|
+
}
|
|
320
|
+
});
|
|
294
321
|
Object.defineProperty(exports, 'EventingSchema', {
|
|
295
322
|
enumerable: true,
|
|
296
323
|
get: function () {
|
|
@@ -309,6 +336,12 @@ Object.defineProperty(exports, 'WebhooksSchema', {
|
|
|
309
336
|
return WebhooksSchema;
|
|
310
337
|
}
|
|
311
338
|
});
|
|
339
|
+
Object.defineProperty(exports, 'hasAdminUiSdk', {
|
|
340
|
+
enumerable: true,
|
|
341
|
+
get: function () {
|
|
342
|
+
return hasAdminUiSdk;
|
|
343
|
+
}
|
|
344
|
+
});
|
|
312
345
|
Object.defineProperty(exports, 'hasCommerceEvents', {
|
|
313
346
|
enumerable: true,
|
|
314
347
|
get: function () {
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
* governing permissions and limitations under the License.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import { n as CommerceAppConfigOutputModel } from "../app-
|
|
16
|
-
import * as _adobe_aio_commerce_lib_core_responses0 from "@adobe/aio-commerce-lib-core/responses";
|
|
15
|
+
import { n as CommerceAppConfigOutputModel } from "../app-DJr-mN9d.mjs";
|
|
16
|
+
import * as _$_adobe_aio_commerce_lib_core_responses0 from "@adobe/aio-commerce-lib-core/responses";
|
|
17
17
|
import { RuntimeActionParams } from "@adobe/aio-commerce-lib-core/params";
|
|
18
18
|
|
|
19
19
|
//#region source/actions/app-config.d.ts
|
|
@@ -24,6 +24,6 @@ type RuntimeActionFactoryArgs = {
|
|
|
24
24
|
/** Factory to create the route handler for the `app-config` action. */
|
|
25
25
|
declare const appConfigRuntimeAction: ({
|
|
26
26
|
appConfig
|
|
27
|
-
}: RuntimeActionFactoryArgs) => (params: RuntimeActionParams) => Promise<_adobe_aio_commerce_lib_core_responses0.ActionResponse>;
|
|
27
|
+
}: RuntimeActionFactoryArgs) => (params: RuntimeActionParams) => Promise<_$_adobe_aio_commerce_lib_core_responses0.ActionResponse>;
|
|
28
28
|
//#endregion
|
|
29
29
|
export { appConfigRuntimeAction };
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import { n as logger, t as HttpActionRouter } from "../router-BxaxEEu3.mjs";
|
|
16
|
-
import { t as validateCommerceAppConfig } from "../validate-
|
|
16
|
+
import { t as validateCommerceAppConfig } from "../validate-CqJdGzyZ.mjs";
|
|
17
17
|
import { ok } from "@adobe/aio-commerce-lib-core/responses";
|
|
18
18
|
|
|
19
19
|
//#region source/actions/app-config.ts
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* governing permissions and limitations under the License.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import * as _adobe_aio_commerce_lib_core_responses0 from "@adobe/aio-commerce-lib-core/responses";
|
|
15
|
+
import * as _$_adobe_aio_commerce_lib_core_responses0 from "@adobe/aio-commerce-lib-core/responses";
|
|
16
16
|
import { BusinessConfigSchema } from "@adobe/aio-commerce-lib-config";
|
|
17
17
|
import { RuntimeActionParams } from "@adobe/aio-commerce-lib-core/params";
|
|
18
18
|
|
|
@@ -24,6 +24,6 @@ type ConfigActionFactoryArgs = {
|
|
|
24
24
|
/** Factory to create the route handler for the `config` action. */
|
|
25
25
|
declare const configRuntimeAction: ({
|
|
26
26
|
configSchema
|
|
27
|
-
}: ConfigActionFactoryArgs) => (params: RuntimeActionParams) => Promise<_adobe_aio_commerce_lib_core_responses0.ActionResponse>;
|
|
27
|
+
}: ConfigActionFactoryArgs) => (params: RuntimeActionParams) => Promise<_$_adobe_aio_commerce_lib_core_responses0.ActionResponse>;
|
|
28
28
|
//#endregion
|
|
29
29
|
export { configRuntimeAction };
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import { n as logger, t as HttpActionRouter } from "../router-BxaxEEu3.mjs";
|
|
16
|
-
import { n as validateCommerceAppConfigDomain } from "../validate-
|
|
17
|
-
import { r as nonEmptyStringValueSchema } from "../schemas-
|
|
16
|
+
import { n as validateCommerceAppConfigDomain } from "../validate-CqJdGzyZ.mjs";
|
|
17
|
+
import { r as nonEmptyStringValueSchema } from "../schemas-CVXHgUhv.mjs";
|
|
18
18
|
import { ok } from "@adobe/aio-commerce-lib-core/responses";
|
|
19
19
|
import * as v from "valibot";
|
|
20
20
|
import { byScopeId, getConfiguration, initialize, setConfiguration } from "@adobe/aio-commerce-lib-config";
|
|
@@ -57,7 +57,11 @@ router.get("/", {
|
|
|
57
57
|
} });
|
|
58
58
|
}
|
|
59
59
|
});
|
|
60
|
-
/**
|
|
60
|
+
/**
|
|
61
|
+
* PUT / - Set configuration (deprecated)
|
|
62
|
+
* @deprecated Use PATCH instead. This endpoint overwrites all values for the scope
|
|
63
|
+
* and does not support partial updates or unset semantics.
|
|
64
|
+
*/
|
|
61
65
|
router.put("/", {
|
|
62
66
|
body: v.object({
|
|
63
67
|
scopeId: nonEmptyStringValueSchema("scopeId"),
|
|
@@ -71,8 +75,35 @@ router.put("/", {
|
|
|
71
75
|
const { configSchema } = rawParams;
|
|
72
76
|
logger.debug(`Setting configuration with scope id: ${req.body.scopeId}`);
|
|
73
77
|
const { scopeId, config } = req.body;
|
|
78
|
+
initialize({ schema: validateCommerceAppConfigDomain(configSchema, "businessConfig.schema") });
|
|
74
79
|
const result = await setConfiguration({ config: config.filter((item) => item.value !== MASKED_PASSWORD_VALUE) }, byScopeId(scopeId), { encryptionKey: rawParams.AIO_COMMERCE_CONFIG_ENCRYPTION_KEY });
|
|
75
80
|
result.config = filterPasswordFields(configSchema, result.config);
|
|
81
|
+
return ok({
|
|
82
|
+
body: result,
|
|
83
|
+
headers: {
|
|
84
|
+
"Cache-Control": "no-store",
|
|
85
|
+
Deprecation: "Wed, 15 Apr 2026 00:00:00 GMT"
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
/** PATCH / - Partially update configuration */
|
|
91
|
+
router.patch("/", {
|
|
92
|
+
body: v.object({
|
|
93
|
+
scopeId: nonEmptyStringValueSchema("scopeId"),
|
|
94
|
+
config: v.array(v.object({
|
|
95
|
+
name: nonEmptyStringValueSchema("config.name"),
|
|
96
|
+
value: v.nullable(v.union([v.string(), v.array(v.string())]))
|
|
97
|
+
}))
|
|
98
|
+
}),
|
|
99
|
+
handler: async (req, ctx) => {
|
|
100
|
+
const { logger, rawParams } = ctx;
|
|
101
|
+
const { configSchema } = rawParams;
|
|
102
|
+
logger.debug(`Patching configuration with scope id: ${req.body.scopeId}`);
|
|
103
|
+
const { scopeId, config } = req.body;
|
|
104
|
+
initialize({ schema: validateCommerceAppConfigDomain(configSchema, "businessConfig.schema") });
|
|
105
|
+
const result = await setConfiguration({ config }, byScopeId(scopeId), { encryptionKey: rawParams.AIO_COMMERCE_CONFIG_ENCRYPTION_KEY });
|
|
106
|
+
result.config = filterPasswordFields(configSchema, result.config);
|
|
76
107
|
return ok({
|
|
77
108
|
body: result,
|
|
78
109
|
headers: { "Cache-Control": "no-store" }
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
* governing permissions and limitations under the License.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import { n as CommerceAppConfigOutputModel } from "../app-
|
|
16
|
-
import {
|
|
17
|
-
import * as _adobe_aio_commerce_lib_core_responses0 from "@adobe/aio-commerce-lib-core/responses";
|
|
15
|
+
import { n as CommerceAppConfigOutputModel } from "../app-DJr-mN9d.mjs";
|
|
16
|
+
import { q as InstallationContext } from "../index-BENO5T7n.mjs";
|
|
17
|
+
import * as _$_adobe_aio_commerce_lib_core_responses0 from "@adobe/aio-commerce-lib-core/responses";
|
|
18
18
|
import { RuntimeActionParams } from "@adobe/aio-commerce-lib-core/params";
|
|
19
19
|
|
|
20
20
|
//#region source/actions/installation.d.ts
|
|
@@ -28,6 +28,6 @@ type RuntimeActionFactoryArgs = {
|
|
|
28
28
|
declare const installationRuntimeAction: ({
|
|
29
29
|
appConfig,
|
|
30
30
|
customScriptsLoader
|
|
31
|
-
}: RuntimeActionFactoryArgs) => (params: RuntimeActionParams) => Promise<_adobe_aio_commerce_lib_core_responses0.ActionResponse>;
|
|
31
|
+
}: RuntimeActionFactoryArgs) => (params: RuntimeActionParams) => Promise<_$_adobe_aio_commerce_lib_core_responses0.ActionResponse>;
|
|
32
32
|
//#endregion
|
|
33
33
|
export { installationRuntimeAction };
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import { n as logger, t as HttpActionRouter } from "../router-BxaxEEu3.mjs";
|
|
16
|
-
import { r as nonEmptyStringValueSchema } from "../schemas-
|
|
17
|
-
import { a as
|
|
16
|
+
import { r as nonEmptyStringValueSchema } from "../schemas-CVXHgUhv.mjs";
|
|
17
|
+
import { a as runValidation, c as isFailedState, i as runUninstallation, l as isInProgressState, n as createInitialUninstallationState, r as runInstallation, s as isCompletedState, t as createInitialInstallationState, u as isSucceededState } from "../management-ByHvVJ12.mjs";
|
|
18
18
|
import { accepted, badRequest, conflict, internalServerError, noContent, ok } from "@adobe/aio-commerce-lib-core/responses";
|
|
19
19
|
import * as v from "valibot";
|
|
20
20
|
import { object, string } from "valibot";
|
|
@@ -266,21 +266,68 @@ const InstallationRequestBodySchema = object({
|
|
|
266
266
|
ioEventsUrl: string(),
|
|
267
267
|
ioEventsEnv: string()
|
|
268
268
|
});
|
|
269
|
-
/** Creates
|
|
270
|
-
function
|
|
269
|
+
/** Creates a workflow state store with the given prefix. */
|
|
270
|
+
function createWorkflowStore(prefix) {
|
|
271
271
|
return createCombinedStore({
|
|
272
|
-
cache: { keyPrefix:
|
|
272
|
+
cache: { keyPrefix: prefix },
|
|
273
273
|
persistent: {
|
|
274
|
-
dirPrefix:
|
|
274
|
+
dirPrefix: prefix,
|
|
275
275
|
shouldPersist: isCompletedState
|
|
276
276
|
}
|
|
277
277
|
});
|
|
278
278
|
}
|
|
279
|
+
/** Creates the installation state store. */
|
|
280
|
+
function createInstallationStore() {
|
|
281
|
+
return createWorkflowStore("installation");
|
|
282
|
+
}
|
|
283
|
+
/** Creates the uninstallation state store. */
|
|
284
|
+
function createUninstallationStore() {
|
|
285
|
+
return createWorkflowStore("uninstallation");
|
|
286
|
+
}
|
|
279
287
|
/** Returns the storage key used to store the current installation ID. */
|
|
280
288
|
function getStorageKey() {
|
|
281
289
|
return "current";
|
|
282
290
|
}
|
|
283
291
|
/**
|
|
292
|
+
* Merges rawParams with body fields, overriding API URLs.
|
|
293
|
+
* Shared by POST /, POST /execution, POST /uninstallation, POST /uninstallation/execution.
|
|
294
|
+
*/
|
|
295
|
+
function buildWorkflowParams(body, rawParams) {
|
|
296
|
+
return {
|
|
297
|
+
...rawParams,
|
|
298
|
+
appData: body.appData,
|
|
299
|
+
AIO_EVENTS_API_BASE_URL: body.ioEventsUrl,
|
|
300
|
+
AIO_COMMERCE_AUTH_IMS_ENVIRONMENT: body.ioEventsEnv,
|
|
301
|
+
AIO_COMMERCE_API_BASE_URL: body.commerceBaseUrl,
|
|
302
|
+
AIO_COMMERCE_API_FLAVOR: body.commerceEnv
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Builds an InstallationContext from merged workflow params.
|
|
307
|
+
* Shared by POST /execution and POST /uninstallation/execution.
|
|
308
|
+
*/
|
|
309
|
+
function buildInstallationContext(params, appConfig, logFn) {
|
|
310
|
+
return {
|
|
311
|
+
appData: params.appData,
|
|
312
|
+
params,
|
|
313
|
+
logger: logFn,
|
|
314
|
+
customScripts: params.customScriptsLoader?.(appConfig, logFn) ?? {}
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Reads state from a store and returns 200 with body or 204.
|
|
319
|
+
* Shared by GET / and GET /uninstallation.
|
|
320
|
+
*/
|
|
321
|
+
async function readStateFromStore(store, logFn) {
|
|
322
|
+
const state = await store.get(getStorageKey());
|
|
323
|
+
if (state) {
|
|
324
|
+
logFn(`Found state: ${state.status}`);
|
|
325
|
+
return ok({ body: state });
|
|
326
|
+
}
|
|
327
|
+
logFn("No state found");
|
|
328
|
+
return noContent();
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
284
331
|
* Creates hooks to sync installation state to storage.
|
|
285
332
|
*/
|
|
286
333
|
function createInstallationHooks(store, logFn) {
|
|
@@ -301,9 +348,14 @@ function createInstallationHooks(store, logFn) {
|
|
|
301
348
|
* Installation action router.
|
|
302
349
|
*
|
|
303
350
|
* Routes:
|
|
304
|
-
* -
|
|
305
|
-
* -
|
|
306
|
-
* - POST /installation/execution
|
|
351
|
+
* - GET /installation - Get current installation status
|
|
352
|
+
* - POST /installation - Start installation (creates plan, invokes execution async)
|
|
353
|
+
* - POST /installation/execution - Execute installation (internal, called async)
|
|
354
|
+
* - POST /installation/validation - Pre-installation validation
|
|
355
|
+
* - POST /installation/uninstallation - Start uninstallation (async)
|
|
356
|
+
* - GET /installation/uninstallation - Get current uninstallation status
|
|
357
|
+
* - POST /installation/uninstallation/execution - Execute uninstallation (internal, called async)
|
|
358
|
+
* - DELETE /installation/uninstallation - Clear uninstallation state only (no offboarding)
|
|
307
359
|
*/
|
|
308
360
|
const router = new HttpActionRouter().use(logger({ name: () => "installation" }));
|
|
309
361
|
/**
|
|
@@ -316,13 +368,7 @@ const router = new HttpActionRouter().use(logger({ name: () => "installation" })
|
|
|
316
368
|
*/
|
|
317
369
|
router.get("/", { handler: async (_req, { logger }) => {
|
|
318
370
|
logger.debug("Getting installation execution status...");
|
|
319
|
-
|
|
320
|
-
if (state) {
|
|
321
|
-
logger.debug(`Found execution: ${state.status}`);
|
|
322
|
-
return ok({ body: state });
|
|
323
|
-
}
|
|
324
|
-
logger.debug("No execution found");
|
|
325
|
-
return noContent();
|
|
371
|
+
return readStateFromStore(await createInstallationStore(), (msg) => logger.debug(msg));
|
|
326
372
|
} });
|
|
327
373
|
/**
|
|
328
374
|
* POST / - Start installation
|
|
@@ -354,17 +400,14 @@ router.post("/", {
|
|
|
354
400
|
const initialState = createInitialInstallationState({ config: appConfig });
|
|
355
401
|
logger.debug(`Created initial state: ${initialState.id}`);
|
|
356
402
|
await store.put(getStorageKey(), initialState);
|
|
357
|
-
const
|
|
403
|
+
const ow = openwhisk();
|
|
404
|
+
const mergedParams = buildWorkflowParams(req.body, rawParams);
|
|
405
|
+
const activation = await ow.actions.invoke({
|
|
358
406
|
name: DEFAULT_ACTION_NAME,
|
|
359
407
|
blocking: false,
|
|
360
408
|
result: false,
|
|
361
409
|
params: {
|
|
362
|
-
...
|
|
363
|
-
appData: req.body.appData,
|
|
364
|
-
AIO_EVENTS_API_BASE_URL: req.body.ioEventsUrl,
|
|
365
|
-
AIO_COMMERCE_AUTH_IMS_ENVIRONMENT: req.body.ioEventsEnv,
|
|
366
|
-
AIO_COMMERCE_API_BASE_URL: req.body.commerceBaseUrl,
|
|
367
|
-
AIO_COMMERCE_API_FLAVOR: req.body.commerceEnv,
|
|
410
|
+
...mergedParams,
|
|
368
411
|
initialState,
|
|
369
412
|
appConfig,
|
|
370
413
|
__ow_path: "/execution",
|
|
@@ -386,18 +429,13 @@ router.post("/", {
|
|
|
386
429
|
* It runs the actual installation workflow and saves state.
|
|
387
430
|
*/
|
|
388
431
|
router.post("/execution", { handler: async (_req, { logger, rawParams }) => {
|
|
389
|
-
const
|
|
432
|
+
const params = rawParams;
|
|
390
433
|
const { initialState, appConfig } = params;
|
|
391
434
|
if (!initialState) return badRequest("initialState is required for execution");
|
|
392
435
|
if (!appConfig) return badRequest("appConfig is required for execution");
|
|
393
436
|
const store = await createInstallationStore();
|
|
394
437
|
const hooks = createInstallationHooks(store, (msg) => logger.debug(msg));
|
|
395
|
-
const installationContext =
|
|
396
|
-
appData,
|
|
397
|
-
params,
|
|
398
|
-
logger,
|
|
399
|
-
customScripts: params.customScriptsLoader?.(appConfig, logger) || {}
|
|
400
|
-
};
|
|
438
|
+
const installationContext = buildInstallationContext(params, appConfig, logger);
|
|
401
439
|
logger.debug(`Executing installation: ${initialState.id}`);
|
|
402
440
|
const result = await runInstallation({
|
|
403
441
|
installationContext,
|
|
@@ -432,14 +470,7 @@ router.post("/validation", {
|
|
|
432
470
|
logger.debug("Running pre-installation validation...");
|
|
433
471
|
const appConfig = rawParams.appConfig;
|
|
434
472
|
if (!appConfig) return internalServerError("Could not find or parse the app.commerce.manifest.json file, is it present and valid?");
|
|
435
|
-
const { appData, ...params } =
|
|
436
|
-
...rawParams,
|
|
437
|
-
appData: req.body.appData,
|
|
438
|
-
AIO_EVENTS_API_BASE_URL: req.body.ioEventsUrl,
|
|
439
|
-
AIO_COMMERCE_AUTH_IMS_ENVIRONMENT: req.body.ioEventsEnv,
|
|
440
|
-
AIO_COMMERCE_API_BASE_URL: req.body.commerceBaseUrl,
|
|
441
|
-
AIO_COMMERCE_API_FLAVOR: req.body.commerceEnv
|
|
442
|
-
};
|
|
473
|
+
const { appData, ...params } = buildWorkflowParams(req.body, rawParams);
|
|
443
474
|
const result = await runValidation({
|
|
444
475
|
validationContext: {
|
|
445
476
|
appData,
|
|
@@ -453,14 +484,107 @@ router.post("/validation", {
|
|
|
453
484
|
}
|
|
454
485
|
});
|
|
455
486
|
/**
|
|
456
|
-
*
|
|
487
|
+
* GET /uninstallation - Get current uninstallation status
|
|
488
|
+
*
|
|
489
|
+
* Returns 200 with state if an uninstallation has been started, 204 otherwise.
|
|
490
|
+
*/
|
|
491
|
+
router.get("/uninstallation", { handler: async (_req, { logger }) => {
|
|
492
|
+
logger.debug("Getting uninstallation execution status...");
|
|
493
|
+
return readStateFromStore(await createUninstallationStore(), (msg) => logger.debug(msg));
|
|
494
|
+
} });
|
|
495
|
+
/**
|
|
496
|
+
* POST /uninstallation - Start uninstallation (async)
|
|
497
|
+
*
|
|
498
|
+
* Flow:
|
|
499
|
+
* 1. Check uninstallation store for existing state
|
|
500
|
+
* 2. If in-progress: return 409 Conflict
|
|
501
|
+
* 3. Create initial uninstall state, save to store
|
|
502
|
+
* 4. Invoke POST /uninstallation/execution async via openwhisk
|
|
503
|
+
* 5. Return 202 Accepted with initial state
|
|
504
|
+
*/
|
|
505
|
+
router.post("/uninstallation", {
|
|
506
|
+
body: InstallationRequestBodySchema,
|
|
507
|
+
handler: async (req, { logger, rawParams }) => {
|
|
508
|
+
logger.debug("Starting async uninstallation...");
|
|
509
|
+
const appConfig = rawParams.appConfig;
|
|
510
|
+
if (!appConfig) return internalServerError("Could not find or parse the app.commerce.manifest.json file, is it present and valid?");
|
|
511
|
+
const store = await createUninstallationStore();
|
|
512
|
+
const existingState = await store.get(getStorageKey());
|
|
513
|
+
if (existingState && isInProgressState(existingState)) {
|
|
514
|
+
logger.debug(`Uninstallation already in progress: ${existingState.status}`);
|
|
515
|
+
return conflict("Uninstallation is already in progress. Wait for it to complete.");
|
|
516
|
+
}
|
|
517
|
+
const initialState = createInitialUninstallationState({ config: appConfig });
|
|
518
|
+
logger.debug(`Created initial uninstall state: ${initialState.id}`);
|
|
519
|
+
await store.put(getStorageKey(), initialState);
|
|
520
|
+
const workflowParams = buildWorkflowParams(req.body, rawParams);
|
|
521
|
+
const activation = await openwhisk().actions.invoke({
|
|
522
|
+
name: DEFAULT_ACTION_NAME,
|
|
523
|
+
blocking: false,
|
|
524
|
+
result: false,
|
|
525
|
+
params: {
|
|
526
|
+
...workflowParams,
|
|
527
|
+
initialState,
|
|
528
|
+
appConfig,
|
|
529
|
+
__ow_path: "/uninstallation/execution",
|
|
530
|
+
__ow_method: "post"
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
logger.debug(`Async uninstallation started: ${activation.activationId}`);
|
|
534
|
+
return accepted({ body: {
|
|
535
|
+
message: "Uninstallation started",
|
|
536
|
+
activationId: activation.activationId,
|
|
537
|
+
...initialState
|
|
538
|
+
} });
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
/**
|
|
542
|
+
* POST /uninstallation/execution - Execute uninstallation (internal, called async by POST /uninstallation)
|
|
543
|
+
*
|
|
544
|
+
* Flow:
|
|
545
|
+
* 1. Build InstallationContext from params
|
|
546
|
+
* 2. Run uninstallation workflow with hooks (hooks persist state per step)
|
|
547
|
+
* 3. Save final state to uninstallation store
|
|
548
|
+
* 4. On success, clear installation store
|
|
549
|
+
* 5. Return 200 on success, 500 on failure
|
|
550
|
+
*/
|
|
551
|
+
router.post("/uninstallation/execution", { handler: async (_req, { logger, rawParams }) => {
|
|
552
|
+
const params = rawParams;
|
|
553
|
+
const { initialState, appConfig } = params;
|
|
554
|
+
if (!initialState) return badRequest("initialState is required for execution");
|
|
555
|
+
if (!appConfig) return badRequest("appConfig is required for execution");
|
|
556
|
+
const store = await createUninstallationStore();
|
|
557
|
+
const hooks = createInstallationHooks(store, (msg) => logger.debug(msg));
|
|
558
|
+
const installationContext = buildInstallationContext(params, appConfig, logger);
|
|
559
|
+
logger.debug(`Executing uninstallation: ${initialState.id}`);
|
|
560
|
+
const result = await runUninstallation({
|
|
561
|
+
installationContext,
|
|
562
|
+
config: appConfig,
|
|
563
|
+
initialState,
|
|
564
|
+
hooks
|
|
565
|
+
});
|
|
566
|
+
await store.put(getStorageKey(), result);
|
|
567
|
+
logger.debug(`Uninstallation completed: ${result.status}`);
|
|
568
|
+
if (isSucceededState(result)) {
|
|
569
|
+
await (await createInstallationStore()).delete(getStorageKey());
|
|
570
|
+
logger.debug("Cleared installation state after successful uninstallation");
|
|
571
|
+
}
|
|
572
|
+
if (isFailedState(result)) return internalServerError({ body: {
|
|
573
|
+
message: "Uninstallation failed",
|
|
574
|
+
error: result.error,
|
|
575
|
+
state: result
|
|
576
|
+
} });
|
|
577
|
+
return ok({ body: result });
|
|
578
|
+
} });
|
|
579
|
+
/**
|
|
580
|
+
* DELETE /uninstallation - Clear uninstallation state
|
|
457
581
|
*
|
|
458
|
-
*
|
|
582
|
+
* Removes the stored uninstallation state without triggering any offboarding.
|
|
459
583
|
*/
|
|
460
|
-
router.delete("/", { handler: async (_req, { logger }) => {
|
|
461
|
-
logger.debug("Clearing
|
|
462
|
-
await (await
|
|
463
|
-
logger.debug("
|
|
584
|
+
router.delete("/uninstallation", { handler: async (_req, { logger }) => {
|
|
585
|
+
logger.debug("Clearing uninstallation state...");
|
|
586
|
+
await (await createUninstallationStore()).delete(getStorageKey());
|
|
587
|
+
logger.debug("Uninstallation state cleared");
|
|
464
588
|
return noContent();
|
|
465
589
|
} });
|
|
466
590
|
/** Factory to create the route handler for the `installation` action. */
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
* governing permissions and limitations under the License.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import * as _adobe_aio_commerce_lib_core_responses0 from "@adobe/aio-commerce-lib-core/responses";
|
|
16
|
-
import * as _adobe_aio_commerce_lib_core_params0 from "@adobe/aio-commerce-lib-core/params";
|
|
15
|
+
import * as _$_adobe_aio_commerce_lib_core_responses0 from "@adobe/aio-commerce-lib-core/responses";
|
|
16
|
+
import * as _$_adobe_aio_commerce_lib_core_params0 from "@adobe/aio-commerce-lib-core/params";
|
|
17
17
|
|
|
18
18
|
//#region source/actions/scope-tree.d.ts
|
|
19
19
|
/** The handler method for the `scope-tree` action. */
|
|
20
|
-
declare const scopeTreeRuntimeAction: (args: _adobe_aio_commerce_lib_core_params0.RuntimeActionParams) => Promise<_adobe_aio_commerce_lib_core_responses0.ActionResponse>;
|
|
20
|
+
declare const scopeTreeRuntimeAction: (args: _$_adobe_aio_commerce_lib_core_params0.RuntimeActionParams) => Promise<_$_adobe_aio_commerce_lib_core_responses0.ActionResponse>;
|
|
21
21
|
//#endregion
|
|
22
22
|
export { scopeTreeRuntimeAction };
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import { n as logger, t as HttpActionRouter } from "../router-BxaxEEu3.mjs";
|
|
16
|
-
import { r as nonEmptyStringValueSchema } from "../schemas-
|
|
16
|
+
import { r as nonEmptyStringValueSchema } from "../schemas-CVXHgUhv.mjs";
|
|
17
17
|
import { t as inspect } from "../logging-XIUXDK5T.mjs";
|
|
18
18
|
import { internalServerError, nonAuthoritativeInformation, ok } from "@adobe/aio-commerce-lib-core/responses";
|
|
19
19
|
import * as v from "valibot";
|
|
@@ -18,7 +18,7 @@ import * as v from "valibot";
|
|
|
18
18
|
/** The schema used to validate the commerce app config file. */
|
|
19
19
|
declare const CommerceAppConfigSchema: v.LooseObjectSchema<{
|
|
20
20
|
readonly metadata: v.ObjectSchema<{
|
|
21
|
-
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string value for '${string}'`>, v.RegexAction<string, `Only alphanumeric characters and hyphens are allowed in string value of "${string}"${string}`>]>;
|
|
21
|
+
readonly id: v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string value for '${string}'`>, v.RegexAction<string, `Only alphanumeric characters and hyphens are allowed in string value of "${string}"${string}`>]>, v.MaxLengthAction<string, 100, "The application id must not be longer than 100 characters">]>;
|
|
22
22
|
readonly displayName: v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for the ${string}`>, v.NonEmptyAction<string, `The ${string} must not be empty`>]>, v.MaxLengthAction<string, 50, "The application display name must not be longer than 50 characters">]>;
|
|
23
23
|
readonly description: v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for the ${string}`>, v.NonEmptyAction<string, `The ${string} must not be empty`>]>, v.MaxLengthAction<string, 255, "The metadata description must not be longer than 255 characters">]>;
|
|
24
24
|
readonly version: v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for the ${string}`>, v.NonEmptyAction<string, `The ${string} must not be empty`>]>, v.RegexAction<string, "The version must follow semantic versioning (semver) format: Major.Minor.Patch (e.g., '1.0.0', '2.3.1')">]>;
|
|
@@ -171,6 +171,18 @@ declare const CommerceAppConfigSchema: v.LooseObjectSchema<{
|
|
|
171
171
|
}, undefined>, "Expected an array of external events">;
|
|
172
172
|
}, undefined>, "Expected an array of external event sources">, undefined>;
|
|
173
173
|
}, undefined>, undefined>;
|
|
174
|
+
readonly adminUiSdk: v.OptionalSchema<v.ObjectSchema<{
|
|
175
|
+
readonly registration: v.ObjectSchema<{
|
|
176
|
+
readonly menuItems: v.ArraySchema<v.ObjectSchema<{
|
|
177
|
+
readonly id: v.StringSchema<undefined>;
|
|
178
|
+
readonly title: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
179
|
+
readonly parent: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
180
|
+
readonly sortOrder: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
|
|
181
|
+
readonly sandbox: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
182
|
+
readonly isSection: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
183
|
+
}, undefined>, undefined>;
|
|
184
|
+
}, undefined>;
|
|
185
|
+
}, undefined>, undefined>;
|
|
174
186
|
readonly installation: v.OptionalSchema<v.ObjectSchema<{
|
|
175
187
|
readonly messages: v.OptionalSchema<v.ObjectSchema<{
|
|
176
188
|
readonly preInstallation: v.OptionalSchema<v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string value for '${string}'`>, v.NonEmptyAction<string, `The value of "${string}" must not be empty`>]>, v.MaxLengthAction<string, 1000, "The preInstallation message must not be longer than 1000 characters">]>, undefined>;
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
* governing permissions and limitations under the License.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import { a as findNearestPackageJson, c as isESM, i as detectPackageManager, l as makeOutputDirFor, n as readCommerceAppConfig, o as getExecCommand, s as getProjectRootDirectory, t as parseCommerceAppConfig, u as readPackageJson } from "../config-
|
|
16
|
+
import { a as hasCustomInstallationSteps } from "../webhooks-CYo-pqbR.mjs";
|
|
17
|
+
import { c as hasBusinessConfigSchema, i as getConfigDomains, t as validateCommerceAppConfig } from "../validate-CqJdGzyZ.mjs";
|
|
18
|
+
import { a as findNearestPackageJson, c as isESM, i as detectPackageManager, l as makeOutputDirFor, n as readCommerceAppConfig, o as getExecCommand, s as getProjectRootDirectory, t as parseCommerceAppConfig, u as readPackageJson } from "../config-BohwKkQS.mjs";
|
|
19
19
|
import { t as stringifyError } from "../error-DHlYzkbb.mjs";
|
|
20
20
|
import { t as inspect } from "../logging-XIUXDK5T.mjs";
|
|
21
21
|
import { CommerceSdkValidationError } from "@adobe/aio-commerce-lib-core/error";
|