@adobe/aio-commerce-lib-app 0.3.2 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +1 -4
  3. package/bin/cli.mjs +24 -0
  4. package/dist/cjs/actions/app-config.cjs +27 -0
  5. package/dist/cjs/actions/app-config.d.cts +15 -0
  6. package/dist/cjs/actions/config.cjs +79 -0
  7. package/dist/cjs/actions/config.d.cts +15 -0
  8. package/dist/cjs/actions/installation.cjs +424 -0
  9. package/dist/cjs/actions/{index.d.cts → installation.d.cts} +4 -3
  10. package/dist/cjs/actions/scope-tree.cjs +97 -0
  11. package/dist/cjs/actions/scope-tree.d.cts +8 -0
  12. package/dist/cjs/{app-Dx0ca6oL.d.cts → app-PTKvEBea.d.cts} +6 -6
  13. package/dist/cjs/commands/generate/actions/templates/app-management/app-config.js.template +22 -0
  14. package/dist/cjs/commands/generate/actions/templates/app-management/installation.js.template +1 -1
  15. package/dist/cjs/commands/generate/actions/templates/business-configuration/config.js.template +22 -0
  16. package/dist/cjs/commands/generate/actions/templates/business-configuration/scope-tree.js.template +18 -0
  17. package/dist/cjs/commands/index.cjs +91 -106
  18. package/dist/cjs/config/index.cjs +21 -19
  19. package/dist/cjs/config/index.d.cts +32 -332
  20. package/dist/cjs/error-DJ2UAPH2.cjs +24 -0
  21. package/dist/cjs/installation-nwF2RC7F.cjs +241 -0
  22. package/dist/cjs/{logging-DYwr5WQk.cjs → logging-IDRQG0as.cjs} +2 -2
  23. package/dist/cjs/management/index.cjs +9 -8
  24. package/dist/cjs/management/index.d.cts +2 -2
  25. package/dist/cjs/parser-DIchX9SL.cjs +267 -0
  26. package/dist/cjs/router-DCw7oEQ9.cjs +417 -0
  27. package/dist/cjs/{management-Dm5h0E6l.cjs → runner-CUJ8RHzY.cjs} +24 -30
  28. package/dist/{es/index-Bxr3zvCT.d.mts → cjs/runner-Ds2m27Q4.d.cts} +49 -95
  29. package/dist/cjs/schemas-CZ6c8Id9.cjs +98 -0
  30. package/dist/cjs/validate-BegMfe-i.cjs +235 -0
  31. package/dist/es/actions/app-config.d.mts +15 -0
  32. package/dist/es/actions/app-config.mjs +25 -0
  33. package/dist/es/actions/config.d.mts +15 -0
  34. package/dist/es/actions/config.mjs +77 -0
  35. package/dist/es/actions/{index.d.mts → installation.d.mts} +4 -3
  36. package/dist/es/actions/{index.mjs → installation.mjs} +27 -427
  37. package/dist/es/actions/scope-tree.d.mts +8 -0
  38. package/dist/es/actions/scope-tree.mjs +95 -0
  39. package/dist/es/{app-Cx1-6dn0.d.mts → app-vKXaAr6f.d.mts} +6 -6
  40. package/dist/es/commands/generate/actions/templates/app-management/app-config.js.template +22 -0
  41. package/dist/es/commands/generate/actions/templates/app-management/installation.js.template +1 -1
  42. package/dist/es/commands/generate/actions/templates/business-configuration/config.js.template +22 -0
  43. package/dist/es/commands/generate/actions/templates/business-configuration/scope-tree.js.template +18 -0
  44. package/dist/es/commands/index.mjs +68 -84
  45. package/dist/es/config/index.d.mts +32 -332
  46. package/dist/es/config/index.mjs +3 -2
  47. package/dist/es/error-CMV3IjBz.mjs +18 -0
  48. package/dist/es/{error-P7JgUTds.mjs → installation-SWIwhpKT.mjs} +72 -124
  49. package/dist/es/management/index.d.mts +2 -3
  50. package/dist/es/management/index.mjs +1 -1
  51. package/dist/es/parser-CKQyrTB7.mjs +201 -0
  52. package/dist/es/router-CJ4VWoCt.mjs +404 -0
  53. package/dist/es/{management-Y7pwEbNI.mjs → runner-DB2tDBQS.mjs} +17 -24
  54. package/dist/{cjs/index-C5SutkJQ.d.cts → es/runner-Uk7263hG.d.mts} +49 -95
  55. package/dist/es/schemas-B8yIv0_b.mjs +41 -0
  56. package/dist/es/validate-DXI6gwZ2.mjs +187 -0
  57. package/package.json +38 -24
  58. package/dist/cjs/actions/index.cjs +0 -824
  59. package/dist/cjs/commands/generate/actions/templates/app-management/get-app-config.js.template +0 -62
  60. package/dist/cjs/commands/generate/actions/templates/business-configuration/get-config-schema.js.template +0 -63
  61. package/dist/cjs/commands/generate/actions/templates/business-configuration/get-configuration.js.template +0 -104
  62. package/dist/cjs/commands/generate/actions/templates/business-configuration/get-scope-tree.js.template +0 -69
  63. package/dist/cjs/commands/generate/actions/templates/business-configuration/set-configuration.js.template +0 -125
  64. package/dist/cjs/commands/generate/actions/templates/business-configuration/set-custom-scope-tree.js.template +0 -83
  65. package/dist/cjs/commands/generate/actions/templates/business-configuration/sync-commerce-scopes.js.template +0 -113
  66. package/dist/cjs/commands/generate/actions/templates/business-configuration/unsync-commerce-scopes.js.template +0 -56
  67. package/dist/cjs/config-JQ_n-5Nk.cjs +0 -565
  68. package/dist/cjs/error-Byj1DVHZ.cjs +0 -344
  69. package/dist/es/commands/generate/actions/templates/app-management/get-app-config.js.template +0 -62
  70. package/dist/es/commands/generate/actions/templates/business-configuration/get-config-schema.js.template +0 -63
  71. package/dist/es/commands/generate/actions/templates/business-configuration/get-configuration.js.template +0 -104
  72. package/dist/es/commands/generate/actions/templates/business-configuration/get-scope-tree.js.template +0 -69
  73. package/dist/es/commands/generate/actions/templates/business-configuration/set-configuration.js.template +0 -125
  74. package/dist/es/commands/generate/actions/templates/business-configuration/set-custom-scope-tree.js.template +0 -83
  75. package/dist/es/commands/generate/actions/templates/business-configuration/sync-commerce-scopes.js.template +0 -113
  76. package/dist/es/commands/generate/actions/templates/business-configuration/unsync-commerce-scopes.js.template +0 -56
  77. package/dist/es/config-BSGerqCG.mjs +0 -457
  78. /package/dist/es/{logging-VgerMhp6.mjs → logging-CzmXDzxI.mjs} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # @adobe/aio-commerce-lib-app
2
2
 
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [#271](https://github.com/adobe/aio-commerce-sdk/pull/271) [`0170e73`](https://github.com/adobe/aio-commerce-sdk/commit/0170e7340d28367a6f001c9b2ff7e1ec0874a49b) Thanks [@iivvaannxx](https://github.com/iivvaannxx)! - Turn `get-app-config` into a REST-like `app-config` runtime action.
8
+
9
+ - [#271](https://github.com/adobe/aio-commerce-sdk/pull/271) [`0170e73`](https://github.com/adobe/aio-commerce-sdk/commit/0170e7340d28367a6f001c9b2ff7e1ec0874a49b) Thanks [@iivvaannxx](https://github.com/iivvaannxx)! - Introduce `config` and `scope-tree` runtime actions with REST-like API for business configuration.
10
+
11
+ - [#294](https://github.com/adobe/aio-commerce-sdk/pull/294) [`6d5b16a`](https://github.com/adobe/aio-commerce-sdk/commit/6d5b16a7659ab0d83b251921ac478ff7faf0d4e5) Thanks [@iivvaannxx](https://github.com/iivvaannxx)! - General Availability (GA) release of the Adobe Commerce SDK and all libraries.
12
+
13
+ - [#287](https://github.com/adobe/aio-commerce-sdk/pull/287) [`fc16aae`](https://github.com/adobe/aio-commerce-sdk/commit/fc16aaec9b459b58e368379bc3127c3e0d698c6a) Thanks [@oshmyheliuk](https://github.com/oshmyheliuk)! - Changed case format from camelCase to snake_case for Commerce eventing API
14
+
15
+ ### Patch Changes
16
+
17
+ - [#274](https://github.com/adobe/aio-commerce-sdk/pull/274) [`d599ba8`](https://github.com/adobe/aio-commerce-sdk/commit/d599ba8ae30d3139d4ba19d0c63eaf716603f25f) Thanks [@iivvaannxx](https://github.com/iivvaannxx)! - Fix typo: `prioritary` should be `priority`
18
+
19
+ - [#267](https://github.com/adobe/aio-commerce-sdk/pull/267) [`8642288`](https://github.com/adobe/aio-commerce-sdk/commit/8642288be4efd44b375d47e7cb75adb038c08334) Thanks [@jnatherley](https://github.com/jnatherley)! - Implements a rolldown plugin to correctly externalize transitive dependencies of private packages during build, but keep the source code of those same packages bundled.
20
+
21
+ - [#277](https://github.com/adobe/aio-commerce-sdk/pull/277) [`b706ac7`](https://github.com/adobe/aio-commerce-sdk/commit/b706ac73042df4df1f7f77da3d58b7042a65ae9a) Thanks [@iivvaannxx](https://github.com/iivvaannxx)! - Optimize generated `actions` by exposing runtime actions in individual entrypoints.
22
+
23
+ - [#264](https://github.com/adobe/aio-commerce-sdk/pull/264) [`ac8203f`](https://github.com/adobe/aio-commerce-sdk/commit/ac8203f6c9d380dc0c337cc173ea730e66a36439) Thanks [@iivvaannxx](https://github.com/iivvaannxx)! - Support word characters, hyphens, underscores, and dots for external event names
24
+
25
+ - [#293](https://github.com/adobe/aio-commerce-sdk/pull/293) [`86443ef`](https://github.com/adobe/aio-commerce-sdk/commit/86443ef71570c1cbbb3b7398f712157b73933f31) Thanks [@iivvaannxx](https://github.com/iivvaannxx)! - Support any casing in the `runtimeActions` property of the `app.commerce.config` for events.
26
+
27
+ - [#269](https://github.com/adobe/aio-commerce-sdk/pull/269) [`a502120`](https://github.com/adobe/aio-commerce-sdk/commit/a502120d8c16fdc1ed4afc579c5cfd79ec56c8e0) Thanks [@iivvaannxx](https://github.com/iivvaannxx)! - Use a safe CLI wrapper to ensure binaries can always be linked
28
+
29
+ - Updated dependencies [[`d599ba8`](https://github.com/adobe/aio-commerce-sdk/commit/d599ba8ae30d3139d4ba19d0c63eaf716603f25f), [`8642288`](https://github.com/adobe/aio-commerce-sdk/commit/8642288be4efd44b375d47e7cb75adb038c08334), [`0170e73`](https://github.com/adobe/aio-commerce-sdk/commit/0170e7340d28367a6f001c9b2ff7e1ec0874a49b), [`6d5b16a`](https://github.com/adobe/aio-commerce-sdk/commit/6d5b16a7659ab0d83b251921ac478ff7faf0d4e5), [`0170e73`](https://github.com/adobe/aio-commerce-sdk/commit/0170e7340d28367a6f001c9b2ff7e1ec0874a49b), [`a502120`](https://github.com/adobe/aio-commerce-sdk/commit/a502120d8c16fdc1ed4afc579c5cfd79ec56c8e0), [`6d5b16a`](https://github.com/adobe/aio-commerce-sdk/commit/6d5b16a7659ab0d83b251921ac478ff7faf0d4e5), [`fc16aae`](https://github.com/adobe/aio-commerce-sdk/commit/fc16aaec9b459b58e368379bc3127c3e0d698c6a), [`0170e73`](https://github.com/adobe/aio-commerce-sdk/commit/0170e7340d28367a6f001c9b2ff7e1ec0874a49b), [`3398078`](https://github.com/adobe/aio-commerce-sdk/commit/33980787b7874a3615b5946b76af1af36153cf76)]:
30
+ - @adobe/aio-commerce-lib-events@1.0.0
31
+ - @adobe/aio-commerce-lib-config@1.0.0
32
+ - @adobe/aio-commerce-lib-auth@1.0.0
33
+ - @adobe/aio-commerce-lib-core@1.0.0
34
+ - @adobe/aio-commerce-lib-api@1.0.0
35
+
3
36
  ## 0.3.2
4
37
 
5
38
  ### Patch Changes
package/README.md CHANGED
@@ -1,15 +1,12 @@
1
1
  # `@adobe/aio-commerce-lib-app`
2
2
 
3
- > [!WARNING]
4
- > This package is still under development and is not yet ready for use. You might be able to install it, but you may encounter breaking changes.
5
-
6
3
  App configuration management library for Adobe Commerce applications.
7
4
 
8
5
  This library provides tools for defining, validating, and managing configurations for Adobe Commerce applications. It defines the configuration schema, provides validation, and supports multiple configuration file formats with built-in TypeScript support.
9
6
 
10
7
  ## Installation
11
8
 
12
- ```bash
9
+ ```shell
13
10
  npm install @adobe/aio-commerce-lib-app
14
11
  ```
15
12
 
package/bin/cli.mjs ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+
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
+ try {
16
+ await import("../dist/es/commands/index.mjs");
17
+ } catch (e) {
18
+ if (e.code && e.code === "ERR_MODULE_NOT_FOUND") {
19
+ console.error("CLI was not built!");
20
+ process.exit(1);
21
+ }
22
+
23
+ throw e;
24
+ }
@@ -0,0 +1,27 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_schemas = require('../schemas-CZ6c8Id9.cjs');
3
+ const require_router = require('../router-DCw7oEQ9.cjs');
4
+ const require_validate = require('../validate-BegMfe-i.cjs');
5
+ let _adobe_aio_commerce_lib_core_responses = require("@adobe/aio-commerce-lib-core/responses");
6
+
7
+ //#region source/actions/app-config.ts
8
+ /** Router for the app config actions. */
9
+ const router = new require_router.HttpActionRouter().use(require_router.logger({ name: () => "get-app-config" }));
10
+ /** GET / - Get app config */
11
+ router.get("/", { handler: async (_req, { logger, rawParams }) => {
12
+ logger.debug("Validating app config...");
13
+ const { appConfig } = rawParams;
14
+ const config = require_validate.validateCommerceAppConfig(appConfig);
15
+ logger.debug("Successfully validated the app config");
16
+ return (0, _adobe_aio_commerce_lib_core_responses.ok)({ body: config });
17
+ } });
18
+ /** Factory to create the route handler for the `app-config` action. */
19
+ const appConfigRuntimeAction = ({ appConfig }) => async (params) => {
20
+ return await router.handler()({
21
+ ...params,
22
+ appConfig
23
+ });
24
+ };
25
+
26
+ //#endregion
27
+ exports.appConfigRuntimeAction = appConfigRuntimeAction;
@@ -0,0 +1,15 @@
1
+ import { n as CommerceAppConfigOutputModel } from "../app-PTKvEBea.cjs";
2
+ import * as _adobe_aio_commerce_lib_core_responses0 from "@adobe/aio-commerce-lib-core/responses";
3
+ import { RuntimeActionParams } from "@adobe/aio-commerce-lib-core/params";
4
+
5
+ //#region source/actions/app-config.d.ts
6
+ /** Arguments for the runtime action factory. */
7
+ type RuntimeActionFactoryArgs = {
8
+ appConfig: CommerceAppConfigOutputModel;
9
+ };
10
+ /** Factory to create the route handler for the `app-config` action. */
11
+ declare const appConfigRuntimeAction: ({
12
+ appConfig
13
+ }: RuntimeActionFactoryArgs) => (params: RuntimeActionParams) => Promise<_adobe_aio_commerce_lib_core_responses0.ActionResponse>;
14
+ //#endregion
15
+ export { appConfigRuntimeAction };
@@ -0,0 +1,79 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_schemas = require('../schemas-CZ6c8Id9.cjs');
3
+ const require_router = require('../router-DCw7oEQ9.cjs');
4
+ const require_validate = require('../validate-BegMfe-i.cjs');
5
+ let _adobe_aio_commerce_lib_core_responses = require("@adobe/aio-commerce-lib-core/responses");
6
+ let valibot = require("valibot");
7
+ valibot = require_schemas.__toESM(valibot);
8
+ let _adobe_aio_commerce_lib_config = require("@adobe/aio-commerce-lib-config");
9
+
10
+ //#region source/actions/config.ts
11
+ const MASKED_PASSWORD_VALUE = "*****";
12
+ /**
13
+ * Filters password fields from the configuration values.
14
+ * @param schema - The schema to use to filter the values.
15
+ * @param values - The values to filter.
16
+ * @returns The filtered values.
17
+ */
18
+ function filterPasswordFields(schema, values) {
19
+ return values.map((item) => {
20
+ if (schema.find((field) => field.name === item.name)?.type === "password") return {
21
+ ...item,
22
+ value: MASKED_PASSWORD_VALUE
23
+ };
24
+ return item;
25
+ });
26
+ }
27
+ const router = new require_router.HttpActionRouter().use(require_router.logger());
28
+ /** GET / - Retrieve configuration */
29
+ router.get("/", {
30
+ query: valibot.object({ scopeId: require_schemas.nonEmptyStringValueSchema("scopeId") }),
31
+ handler: async (req, ctx) => {
32
+ const { logger, rawParams } = ctx;
33
+ const configSchema = rawParams.configSchema;
34
+ logger.debug("Validating configuration schema...");
35
+ const validatedSchema = require_validate.validateCommerceAppConfigDomain(configSchema, "businessConfig.schema");
36
+ (0, _adobe_aio_commerce_lib_config.initialize)({ schema: validatedSchema });
37
+ const { scopeId } = req.query;
38
+ logger.debug(`Retrieving configuration with scope id: ${scopeId}`);
39
+ const appConfiguration = await (0, _adobe_aio_commerce_lib_config.getConfiguration)((0, _adobe_aio_commerce_lib_config.byScopeId)(scopeId), { encryptionKey: rawParams.AIO_COMMERCE_CONFIG_ENCRYPTION_KEY });
40
+ logger.debug("Masking password values...");
41
+ appConfiguration.config = filterPasswordFields(configSchema, appConfiguration.config);
42
+ return (0, _adobe_aio_commerce_lib_core_responses.ok)({ body: {
43
+ schema: validatedSchema,
44
+ values: appConfiguration
45
+ } });
46
+ }
47
+ });
48
+ /** POST / - Set configuration */
49
+ router.put("/", {
50
+ body: valibot.object({
51
+ scopeId: require_schemas.nonEmptyStringValueSchema("scopeId"),
52
+ config: valibot.array(valibot.object({
53
+ name: require_schemas.nonEmptyStringValueSchema("config.name"),
54
+ value: valibot.union([valibot.string(), valibot.array(valibot.string())])
55
+ }))
56
+ }),
57
+ handler: async (req, ctx) => {
58
+ const { logger, rawParams } = ctx;
59
+ const { configSchema } = rawParams;
60
+ logger.debug(`Setting configuration with scope id: ${req.body.scopeId}`);
61
+ const { scopeId, config } = req.body;
62
+ const result = await (0, _adobe_aio_commerce_lib_config.setConfiguration)({ config: config.filter((item) => item.value !== MASKED_PASSWORD_VALUE) }, (0, _adobe_aio_commerce_lib_config.byScopeId)(scopeId), { encryptionKey: rawParams.AIO_COMMERCE_CONFIG_ENCRYPTION_KEY });
63
+ result.config = filterPasswordFields(configSchema, result.config);
64
+ return (0, _adobe_aio_commerce_lib_core_responses.ok)({
65
+ body: result,
66
+ headers: { "Cache-Control": "no-store" }
67
+ });
68
+ }
69
+ });
70
+ /** Factory to create the route handler for the `config` action. */
71
+ const configRuntimeAction = ({ configSchema }) => async (params) => {
72
+ return await router.handler()({
73
+ ...params,
74
+ configSchema
75
+ });
76
+ };
77
+
78
+ //#endregion
79
+ exports.configRuntimeAction = configRuntimeAction;
@@ -0,0 +1,15 @@
1
+ import * as _adobe_aio_commerce_lib_core_responses0 from "@adobe/aio-commerce-lib-core/responses";
2
+ import { RuntimeActionParams } from "@adobe/aio-commerce-lib-core/params";
3
+ import { BusinessConfigSchema } from "@adobe/aio-commerce-lib-config";
4
+
5
+ //#region source/actions/config.d.ts
6
+ /** The arguments for the config action factory. */
7
+ type ConfigActionFactoryArgs = {
8
+ configSchema: BusinessConfigSchema;
9
+ };
10
+ /** Factory to create the route handler for the `config` action. */
11
+ declare const configRuntimeAction: ({
12
+ configSchema
13
+ }: ConfigActionFactoryArgs) => (params: RuntimeActionParams) => Promise<_adobe_aio_commerce_lib_core_responses0.ActionResponse>;
14
+ //#endregion
15
+ export { configRuntimeAction };
@@ -0,0 +1,424 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_schemas = require('../schemas-CZ6c8Id9.cjs');
3
+ const require_router = require('../router-DCw7oEQ9.cjs');
4
+ const require_runner = require('../runner-CUJ8RHzY.cjs');
5
+ let _adobe_aio_commerce_lib_core_responses = require("@adobe/aio-commerce-lib-core/responses");
6
+ let valibot = require("valibot");
7
+ valibot = require_schemas.__toESM(valibot);
8
+ let _adobe_aio_lib_files = require("@adobe/aio-lib-files");
9
+ let _adobe_aio_lib_state = require("@adobe/aio-lib-state");
10
+ let openwhisk = require("openwhisk");
11
+ openwhisk = require_schemas.__toESM(openwhisk);
12
+
13
+ //#region ../../packages-private/common-utils/source/storage/files-store.ts
14
+ /** Default directory prefix. */
15
+ const DEFAULT_DIR_PREFIX = "store";
16
+ /**
17
+ * Creates a generic key-value store backed by @adobe/aio-lib-files.
18
+ * Provides persistent storage that survives beyond TTL.
19
+ *
20
+ * @typeParam T - The type of data to store.
21
+ * @param options - Configuration options for the store.
22
+ * @returns A KeyValueStore implementation.
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * interface UserProfile {
27
+ * id: string;
28
+ * name: string;
29
+ * email: string;
30
+ * }
31
+ *
32
+ * const store = await createFilesStore<UserProfile>({
33
+ * dirPrefix: "profiles",
34
+ * });
35
+ *
36
+ * await store.put("user-123", { id: "123", name: "John", email: "john@example.com" });
37
+ * const profile = await store.get("user-123");
38
+ * ```
39
+ */
40
+ async function createFilesStore(options = {}) {
41
+ const { dirPrefix = DEFAULT_DIR_PREFIX } = options;
42
+ return new FilesStore(await (0, _adobe_aio_lib_files.init)(), dirPrefix);
43
+ }
44
+ /**
45
+ * Key-value store implementation using @adobe/aio-lib-files.
46
+ */
47
+ var FilesStore = class {
48
+ constructor(files, dirPrefix) {
49
+ this.files = files;
50
+ this.dirPrefix = dirPrefix;
51
+ }
52
+ async get(key) {
53
+ const filePath = this.buildFilePath(key);
54
+ try {
55
+ const content = await this.files.read(filePath);
56
+ if (!content) return null;
57
+ return JSON.parse(content.toString("utf8"));
58
+ } catch {
59
+ return null;
60
+ }
61
+ }
62
+ async put(key, data) {
63
+ const filePath = this.buildFilePath(key);
64
+ await this.files.write(filePath, JSON.stringify(data));
65
+ }
66
+ async delete(key) {
67
+ const filePath = this.buildFilePath(key);
68
+ try {
69
+ const result = await this.files.delete(filePath);
70
+ return Array.isArray(result) && result.length > 0;
71
+ } catch {
72
+ return false;
73
+ }
74
+ }
75
+ buildFilePath(key) {
76
+ return `${this.dirPrefix}/${key}.json`;
77
+ }
78
+ };
79
+
80
+ //#endregion
81
+ //#region ../../packages-private/common-utils/source/storage/state-store.ts
82
+ /** Default TTL for state entries (3 hours in seconds). */
83
+ const DEFAULT_TTL_SECONDS = 10800;
84
+ /** Default key prefix. */
85
+ const DEFAULT_KEY_PREFIX = "store";
86
+ /**
87
+ * Creates a generic key-value store backed by @adobe/aio-lib-state.
88
+ * Provides fast, TTL-based caching for temporary data.
89
+ *
90
+ * @typeParam T - The type of data to store.
91
+ * @param options - Configuration options for the store.
92
+ * @returns A KeyValueStore implementation.
93
+ *
94
+ * @example
95
+ * ```typescript
96
+ * interface UserSession {
97
+ * userId: string;
98
+ * token: string;
99
+ * }
100
+ *
101
+ * const store = await createStateStore<UserSession>({
102
+ * keyPrefix: "session",
103
+ * ttlSeconds: 3600, // 1 hour
104
+ * });
105
+ *
106
+ * await store.put("user-123", { userId: "123", token: "abc" });
107
+ * const session = await store.get("user-123");
108
+ * ```
109
+ */
110
+ async function createStateStore(options = {}) {
111
+ const { keyPrefix = DEFAULT_KEY_PREFIX, ttlSeconds = DEFAULT_TTL_SECONDS } = options;
112
+ return new StateStore(await (0, _adobe_aio_lib_state.init)(), keyPrefix, ttlSeconds);
113
+ }
114
+ /**
115
+ * Key-value store implementation using @adobe/aio-lib-state.
116
+ */
117
+ var StateStore = class {
118
+ constructor(state, keyPrefix, ttlSeconds) {
119
+ this.state = state;
120
+ this.keyPrefix = keyPrefix;
121
+ this.ttlSeconds = ttlSeconds;
122
+ }
123
+ async get(key) {
124
+ const fullKey = this.buildKey(key);
125
+ const result = await this.state.get(fullKey);
126
+ if (!result?.value) return null;
127
+ try {
128
+ return JSON.parse(result.value);
129
+ } catch {
130
+ return null;
131
+ }
132
+ }
133
+ async put(key, data) {
134
+ const fullKey = this.buildKey(key);
135
+ const value = JSON.stringify(data);
136
+ await this.state.put(fullKey, value, { ttl: this.ttlSeconds });
137
+ }
138
+ async delete(key) {
139
+ const fullKey = this.buildKey(key);
140
+ try {
141
+ await this.state.delete(fullKey);
142
+ return true;
143
+ } catch {
144
+ return false;
145
+ }
146
+ }
147
+ buildKey(key) {
148
+ return `${this.keyPrefix}-${key}`;
149
+ }
150
+ };
151
+
152
+ //#endregion
153
+ //#region ../../packages-private/common-utils/source/storage/combined-store.ts
154
+ /** Default TTL for cache (10 minutes). */
155
+ const DEFAULT_CACHE_TTL_SECONDS = 600;
156
+ /**
157
+ * Creates a combined key-value store that uses:
158
+ * - lib-state for fast cache during active operations
159
+ * - lib-files for persistent storage
160
+ *
161
+ * Read strategy: cache first, then persistent storage
162
+ * Write strategy:
163
+ * - Always write to cache for fast reads
164
+ * - Write to persistent storage based on shouldPersist predicate
165
+ *
166
+ * @typeParam T - The type of data to store.
167
+ * @param options - Configuration options for the stores.
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * interface Task {
172
+ * id: string;
173
+ * status: "pending" | "completed";
174
+ * result?: unknown;
175
+ * }
176
+ *
177
+ * const store = await createCombinedStore<Task>({
178
+ * cache: { keyPrefix: "task", ttlSeconds: 600 },
179
+ * persistent: {
180
+ * dirPrefix: "tasks",
181
+ * shouldPersist: (task) => task.status === "completed",
182
+ * },
183
+ * });
184
+ *
185
+ * // During processing: writes to cache only
186
+ * await store.put("task-1", { id: "1", status: "pending" });
187
+ *
188
+ * // On completion (as shouldPersist indicates): writes to both cache and persistent
189
+ * await store.put("task-1", { id: "1", status: "completed", result: {} });
190
+ * ```
191
+ */
192
+ async function createCombinedStore(options = {}) {
193
+ const { cache = {}, persistent = {} } = options;
194
+ const { shouldPersist, ...filesOptions } = persistent;
195
+ const cacheOptions = {
196
+ ttlSeconds: DEFAULT_CACHE_TTL_SECONDS,
197
+ ...cache
198
+ };
199
+ const [cacheStore, persistentStore] = await Promise.all([createStateStore(cacheOptions), createFilesStore(filesOptions)]);
200
+ return new CombinedStore(cacheStore, persistentStore, shouldPersist);
201
+ }
202
+ /**
203
+ * Combined key-value store implementation.
204
+ * Uses lib-state for cache and lib-files for persistence.
205
+ */
206
+ var CombinedStore = class {
207
+ constructor(cache, persistent, shouldPersist) {
208
+ this.cache = cache;
209
+ this.persistent = persistent;
210
+ this.shouldPersist = shouldPersist;
211
+ }
212
+ async get(key) {
213
+ const cached = await this.cache.get(key);
214
+ if (cached !== null && cached !== void 0) return cached;
215
+ const persisted = await this.persistent.get(key);
216
+ if (persisted !== null && persisted !== void 0) {
217
+ await this.cache.put(key, persisted).catch(() => {});
218
+ return persisted;
219
+ }
220
+ return null;
221
+ }
222
+ async put(key, data) {
223
+ await this.cache.put(key, data);
224
+ if (!this.shouldPersist || this.shouldPersist(data)) await this.persistent.put(key, data);
225
+ }
226
+ async delete(key) {
227
+ const [cacheDeleted, persistentDeleted] = await Promise.all([this.cache.delete?.(key) ?? Promise.resolve(false), this.persistent.delete?.(key) ?? Promise.resolve(false)]);
228
+ return cacheDeleted || persistentDeleted;
229
+ }
230
+ };
231
+
232
+ //#endregion
233
+ //#region source/management/installation/schema.ts
234
+ /** Schema for validating Adobe I/O app credentials required for installation. */
235
+ const AppDataSchema = valibot.object({
236
+ consumerOrgId: require_schemas.nonEmptyStringValueSchema("consumerOrgId"),
237
+ orgName: require_schemas.nonEmptyStringValueSchema("orgName"),
238
+ projectId: require_schemas.nonEmptyStringValueSchema("projectId"),
239
+ projectName: require_schemas.nonEmptyStringValueSchema("projectName"),
240
+ projectTitle: require_schemas.nonEmptyStringValueSchema("projectTitle"),
241
+ workspaceId: require_schemas.nonEmptyStringValueSchema("workspaceId"),
242
+ workspaceName: require_schemas.nonEmptyStringValueSchema("workspaceName"),
243
+ workspaceTitle: require_schemas.nonEmptyStringValueSchema("workspaceTitle")
244
+ });
245
+
246
+ //#endregion
247
+ //#region source/actions/installation.ts
248
+ const DEFAULT_ACTION_NAME = "app-management/installation";
249
+ /** Creates an installation state store using lib-core combined storage. */
250
+ function createInstallationStore() {
251
+ return createCombinedStore({
252
+ cache: { keyPrefix: "installation" },
253
+ persistent: {
254
+ dirPrefix: "installation",
255
+ shouldPersist: require_runner.isCompletedState
256
+ }
257
+ });
258
+ }
259
+ /** Returns the storage key used to store the current installation ID. */
260
+ function getStorageKey() {
261
+ return "current";
262
+ }
263
+ /**
264
+ * Creates hooks to sync installation state to storage.
265
+ */
266
+ function createInstallationHooks(store, logFn) {
267
+ const logAndSave = async (message, data) => {
268
+ logFn(message);
269
+ await store.put(getStorageKey(), data);
270
+ };
271
+ return {
272
+ onInstallationStart: (state) => logAndSave("Installation started", state),
273
+ onInstallationFailure: (state) => logAndSave("Installation failed", state),
274
+ onInstallationSuccess: (state) => logAndSave("Installation succeeded", state),
275
+ onStepStart: (event, state) => logAndSave(`Step started: ${event.stepName}`, state),
276
+ onStepSuccess: (event, state) => logAndSave(`Step succeeded: ${event.stepName}`, state),
277
+ onStepFailure: (event, state) => logAndSave(`Step failed: ${event.stepName}`, state)
278
+ };
279
+ }
280
+ /**
281
+ * Installation action router.
282
+ *
283
+ * Routes:
284
+ * - POST /installation - Start installation (creates plan, invokes execution async)
285
+ * - GET /installation/execution - Get current execution status
286
+ * - POST /installation/execution - Execute installation (internal, called async)
287
+ */
288
+ const router = new require_router.HttpActionRouter().use(require_router.logger({ name: () => "installation" }));
289
+ /**
290
+ * GET /installation/execution - Get current execution status
291
+ *
292
+ * Flow:
293
+ * 1. Find execution in state store
294
+ * 2. If found: return execution plan with step statuses
295
+ * 3. If not found: return empty status
296
+ */
297
+ router.get("/", { handler: async (_req, { logger }) => {
298
+ logger.debug("Getting installation execution status...");
299
+ const state = await (await createInstallationStore()).get(getStorageKey());
300
+ if (state) {
301
+ logger.debug(`Found execution: ${state.status}`);
302
+ return (0, _adobe_aio_commerce_lib_core_responses.ok)({ body: state });
303
+ }
304
+ logger.debug("No execution found");
305
+ return (0, _adobe_aio_commerce_lib_core_responses.noContent)();
306
+ } });
307
+ /**
308
+ * POST / - Start installation
309
+ *
310
+ * Flow:
311
+ * 1. Find execution in state store
312
+ * 2. If found and (pending/in-progress or succeeded): return 409 Conflict
313
+ * 3. If not found or failed: create plan, invoke execution async, return 202 Accepted
314
+ */
315
+ router.post("/", {
316
+ body: (0, valibot.object)({
317
+ appData: AppDataSchema,
318
+ commerceBaseUrl: (0, valibot.string)(),
319
+ commerceEnv: (0, valibot.string)(),
320
+ ioEventsUrl: (0, valibot.string)(),
321
+ ioEventsEnv: (0, valibot.string)()
322
+ }),
323
+ handler: async (req, { logger, rawParams }) => {
324
+ logger.debug("Starting installation...");
325
+ const store = await createInstallationStore();
326
+ const existingState = await store.get(getStorageKey());
327
+ if (existingState) {
328
+ if (require_runner.isInProgressState(existingState)) {
329
+ logger.debug(`Installation already in progress: ${existingState.status}`);
330
+ return (0, _adobe_aio_commerce_lib_core_responses.conflict)(`Installation is already ${existingState.status}. Wait for it to complete.`);
331
+ }
332
+ if (require_runner.isSucceededState(existingState)) {
333
+ logger.debug("Installation already succeeded");
334
+ return (0, _adobe_aio_commerce_lib_core_responses.conflict)("Installation has already completed successfully.");
335
+ }
336
+ logger.debug("Previous installation failed, allowing retry");
337
+ }
338
+ const appConfig = rawParams.appConfig;
339
+ if (!appConfig) return (0, _adobe_aio_commerce_lib_core_responses.internalServerError)("Could not find or parse the app.commerce.manifest.json file, is it present and valid?");
340
+ const initialState = require_runner.createInitialInstallationState({ config: appConfig });
341
+ logger.debug(`Created initial state: ${initialState.id}`);
342
+ await store.put(getStorageKey(), initialState);
343
+ const activation = await (0, openwhisk.default)().actions.invoke({
344
+ name: DEFAULT_ACTION_NAME,
345
+ blocking: false,
346
+ result: false,
347
+ params: {
348
+ ...rawParams,
349
+ appData: req.body.appData,
350
+ AIO_EVENTS_API_BASE_URL: req.body.ioEventsUrl,
351
+ AIO_COMMERCE_AUTH_IMS_ENVIRONMENT: req.body.ioEventsEnv,
352
+ AIO_COMMERCE_API_BASE_URL: req.body.commerceBaseUrl,
353
+ AIO_COMMERCE_API_FLAVOR: req.body.commerceEnv,
354
+ initialState,
355
+ appConfig,
356
+ __ow_path: "/execution",
357
+ __ow_method: "post"
358
+ }
359
+ });
360
+ logger.debug(`Async execution started: ${activation.activationId}`);
361
+ return (0, _adobe_aio_commerce_lib_core_responses.accepted)({ body: {
362
+ message: "Installation started",
363
+ activationId: activation.activationId,
364
+ ...initialState
365
+ } });
366
+ }
367
+ });
368
+ /**
369
+ * POST /installation/execution - Execute installation (internal)
370
+ *
371
+ * This endpoint is called asynchronously by POST /installation.
372
+ * It runs the actual installation workflow and saves state.
373
+ */
374
+ router.post("/execution", { handler: async (_req, { logger, rawParams }) => {
375
+ const { appData, ...params } = rawParams;
376
+ const { initialState, appConfig } = params;
377
+ if (!initialState) return (0, _adobe_aio_commerce_lib_core_responses.badRequest)("initialState is required for execution");
378
+ if (!appConfig) return (0, _adobe_aio_commerce_lib_core_responses.badRequest)("appConfig is required for execution");
379
+ const store = await createInstallationStore();
380
+ const hooks = createInstallationHooks(store, (msg) => logger.debug(msg));
381
+ const installationContext = {
382
+ appData,
383
+ params,
384
+ logger,
385
+ customScripts: params.customScriptsLoader?.(appConfig, logger) || {}
386
+ };
387
+ logger.debug(`Executing installation: ${initialState.id}`);
388
+ const result = await require_runner.runInstallation({
389
+ installationContext,
390
+ config: appConfig,
391
+ initialState,
392
+ hooks
393
+ });
394
+ await store.put(getStorageKey(), result);
395
+ logger.debug(`Installation completed: ${result.status}`);
396
+ if (require_runner.isFailedState(result)) return (0, _adobe_aio_commerce_lib_core_responses.internalServerError)({ body: {
397
+ message: "Installation failed",
398
+ error: result.error,
399
+ state: result
400
+ } });
401
+ return (0, _adobe_aio_commerce_lib_core_responses.ok)({ body: result });
402
+ } });
403
+ /**
404
+ * DELETE / - Clear installation state
405
+ *
406
+ * This endpoint allows clearing the installation state.
407
+ */
408
+ router.delete("/", { handler: async (_req, { logger }) => {
409
+ logger.debug("Clearing installation state...");
410
+ await (await createInstallationStore()).delete(getStorageKey());
411
+ logger.debug("Installation state cleared");
412
+ return (0, _adobe_aio_commerce_lib_core_responses.noContent)();
413
+ } });
414
+ /** Factory to create the route handler for the `installation` action. */
415
+ const installationRuntimeAction = ({ appConfig, customScriptsLoader }) => async (params) => {
416
+ return await router.handler()({
417
+ ...params,
418
+ appConfig,
419
+ customScriptsLoader
420
+ });
421
+ };
422
+
423
+ //#endregion
424
+ exports.installationRuntimeAction = installationRuntimeAction;
@@ -1,15 +1,16 @@
1
- import { n as CommerceAppConfigOutputModel } from "../app-Dx0ca6oL.cjs";
2
- import { P as InstallationContext } from "../index-C5SutkJQ.cjs";
1
+ import { n as CommerceAppConfigOutputModel } from "../app-PTKvEBea.cjs";
2
+ import { P as InstallationContext } from "../runner-Ds2m27Q4.cjs";
3
3
  import * as _adobe_aio_commerce_lib_core_responses0 from "@adobe/aio-commerce-lib-core/responses";
4
4
  import { RuntimeActionParams } from "@adobe/aio-commerce-lib-core/params";
5
5
 
6
6
  //#region source/actions/installation.d.ts
7
7
  type CustomScriptsLoader = (config: CommerceAppConfigOutputModel, logger: InstallationContext["logger"]) => Record<string, unknown>;
8
+ /** Arguments for the runtime action factory. */
8
9
  type RuntimeActionFactoryArgs = {
9
10
  appConfig: CommerceAppConfigOutputModel;
10
11
  customScriptsLoader?: CustomScriptsLoader;
11
12
  };
12
- /** The route handler for the runtime action. */
13
+ /** Factory to create the route handler for the `installation` action. */
13
14
  declare const installationRuntimeAction: ({
14
15
  appConfig,
15
16
  customScriptsLoader