@adobe/aio-commerce-lib-app 1.6.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/cjs/actions/app-config/index.cjs +202 -0
  3. package/dist/cjs/actions/app-config/index.d.cts +31 -0
  4. package/dist/cjs/actions/{config.cjs → config/index.cjs} +61 -33
  5. package/dist/{es/actions/config.d.mts → cjs/actions/config/index.d.cts} +10 -7
  6. package/dist/cjs/actions/{installation.cjs → installation/index.cjs} +43 -30
  7. package/dist/{es/actions/installation.d.mts → cjs/actions/installation/index.d.cts} +10 -8
  8. package/dist/cjs/actions/{registration.cjs → registration/index.cjs} +16 -6
  9. package/dist/cjs/actions/{registration.d.cts → registration/index.d.cts} +8 -8
  10. package/dist/cjs/actions/{scope-tree.cjs → scope-tree/index.cjs} +51 -14
  11. package/dist/cjs/actions/{scope-tree.d.cts → scope-tree/index.d.cts} +1 -1
  12. package/dist/cjs/{admin-ui-sdk-DZZJCrdT.d.cts → admin-ui-sdk-EU915zlR.d.cts} +7 -8
  13. package/dist/cjs/app-DrYHK-z1.d.cts +1629 -0
  14. package/dist/cjs/commands/index.cjs +12 -18
  15. package/dist/cjs/config/index.cjs +2 -2
  16. package/dist/cjs/config/index.d.cts +36 -976
  17. package/dist/cjs/{config-FNMclIFO.cjs → config-D-s0GSep.cjs} +1 -1
  18. package/dist/cjs/{index-Dw2NvVOY.d.cts → index-B5gJ-q4U.d.cts} +172 -3
  19. package/dist/{es/actions/app-config.d.mts → cjs/index-BXm8UbK7.d.cts} +1 -13
  20. package/dist/cjs/management/index.cjs +1 -1
  21. package/dist/cjs/management/index.d.cts +1 -2
  22. package/dist/cjs/{management-Cvsz4VMf.cjs → management-Dehz9qSJ.cjs} +81 -43
  23. package/dist/cjs/openapi-Cux6K4ZD.cjs +3072 -0
  24. package/dist/cjs/{validate-DydOAZha.cjs → validate-oAOpyFyb.cjs} +46 -14
  25. package/dist/es/actions/app-config/index.d.mts +31 -0
  26. package/dist/es/actions/app-config/index.mjs +199 -0
  27. package/dist/{cjs/actions/config.d.cts → es/actions/config/index.d.mts} +10 -7
  28. package/dist/es/actions/{config.mjs → config/index.mjs} +60 -32
  29. package/dist/{cjs/actions/installation.d.cts → es/actions/installation/index.d.mts} +10 -8
  30. package/dist/es/actions/{installation.mjs → installation/index.mjs} +42 -30
  31. package/dist/es/actions/{registration.d.mts → registration/index.d.mts} +8 -8
  32. package/dist/es/actions/{registration.mjs → registration/index.mjs} +16 -6
  33. package/dist/es/actions/{scope-tree.d.mts → scope-tree/index.d.mts} +1 -1
  34. package/dist/es/actions/{scope-tree.mjs → scope-tree/index.mjs} +50 -13
  35. package/dist/es/{admin-ui-sdk-hu6iWr0A.d.mts → admin-ui-sdk-BwnD0xjK.d.mts} +6 -9
  36. package/dist/es/app-DrYHK-z1.d.mts +1629 -0
  37. package/dist/es/commands/index.mjs +12 -18
  38. package/dist/es/config/index.d.mts +36 -975
  39. package/dist/es/config/index.mjs +2 -2
  40. package/dist/es/{config-CcE0EBG7.mjs → config-3I4eLyyR.mjs} +1 -1
  41. package/dist/{cjs/actions/app-config.d.cts → es/index-B0XqHwY5.d.mts} +2 -14
  42. package/dist/es/{index-Bo0tQsVq.d.mts → index-DLMbTtKS.d.mts} +172 -3
  43. package/dist/es/management/index.d.mts +1 -2
  44. package/dist/es/management/index.mjs +1 -1
  45. package/dist/es/{management-BZ4Y6lVp.mjs → management-BUX-w2Ji.mjs} +81 -44
  46. package/dist/es/openapi-B6uP0SRn.mjs +3024 -0
  47. package/dist/es/{validate-Du3LhCre.mjs → validate-Dfajrp99.mjs} +35 -15
  48. package/package.json +17 -10
  49. package/dist/cjs/actions/app-config.cjs +0 -54
  50. package/dist/cjs/app-CakwxQvs.d.cts +0 -673
  51. package/dist/cjs/step-CKVE0aJi.d.cts +0 -187
  52. package/dist/es/actions/app-config.mjs +0 -53
  53. package/dist/es/app-CakwxQvs.d.mts +0 -673
  54. package/dist/es/step-D64mMPrt.d.mts +0 -187
@@ -15,8 +15,8 @@
15
15
  const require_chunk = require('./chunk-Cozy-1ZF.cjs');
16
16
  const require_schemas = require('./schemas-FngDuIeo.cjs');
17
17
  const require_webhooks = require('./webhooks-tbZy9G3p.cjs');
18
- let _adobe_aio_commerce_lib_config = require("@adobe/aio-commerce-lib-config");
19
18
  let _adobe_aio_commerce_lib_core_error = require("@adobe/aio-commerce-lib-core/error");
19
+ let _adobe_aio_commerce_lib_config = require("@adobe/aio-commerce-lib-config");
20
20
  let valibot = require("valibot");
21
21
  valibot = require_chunk.__toESM(valibot, 1);
22
22
 
@@ -61,19 +61,6 @@ function hasMetadata(config) {
61
61
  return config.metadata !== void 0;
62
62
  }
63
63
 
64
- //#endregion
65
- //#region source/config/schema/app.ts
66
- /** biome-ignore-all lint/performance/noBarrelFile: We want to have all the schema exports in one file. */
67
- /** The schema used to validate the commerce app config file. */
68
- const CommerceAppConfigSchema = valibot.looseObject({
69
- metadata: MetadataSchema,
70
- businessConfig: valibot.optional(_adobe_aio_commerce_lib_config.SchemaBusinessConfig),
71
- eventing: valibot.optional(require_webhooks.EventingSchema),
72
- adminUiSdk: valibot.optional(require_webhooks.AdminUiSdkSchema),
73
- installation: valibot.optional(require_webhooks.InstallationSchema),
74
- webhooks: valibot.optional(require_webhooks.WebhooksSchema)
75
- });
76
-
77
64
  //#endregion
78
65
  //#region source/config/schema/domains.ts
79
66
  /** The individual validatable domains of the app config. */
@@ -120,6 +107,39 @@ function hasConfigDomain(config, domain) {
120
107
  return getConfigDomains(config).has(domain);
121
108
  }
122
109
 
110
+ //#endregion
111
+ //#region source/config/schema/app.ts
112
+ /** biome-ignore-all lint/performance/noBarrelFile: We want to have all the schema exports in one file. */
113
+ /** The schema used to validate the commerce app config file. */
114
+ const CommerceAppConfigSchema = valibot.looseObject({
115
+ metadata: MetadataSchema,
116
+ businessConfig: valibot.optional(_adobe_aio_commerce_lib_config.SchemaBusinessConfig),
117
+ eventing: valibot.optional(require_webhooks.EventingSchema),
118
+ adminUiSdk: valibot.optional(require_webhooks.AdminUiSdkSchema),
119
+ installation: valibot.optional(require_webhooks.InstallationSchema),
120
+ webhooks: valibot.optional(require_webhooks.WebhooksSchema)
121
+ });
122
+ /**
123
+ * Returns true if the given config domains require installation, false otherwise.
124
+ * @param domains - The config domains to check.
125
+ */
126
+ function requiresInstallationFromDomains(domains) {
127
+ return [
128
+ "installation.customInstallationSteps",
129
+ "eventing.commerce",
130
+ "eventing.external",
131
+ "webhooks",
132
+ "adminUiSdk"
133
+ ].some((feature) => domains.has(feature));
134
+ }
135
+ /**
136
+ * Returns true if the given config requires installation, false otherwise.
137
+ * @param config - The commerce app config to check.
138
+ */
139
+ function requiresInstallation(config) {
140
+ return requiresInstallationFromDomains(getConfigDomains(config));
141
+ }
142
+
123
143
  //#endregion
124
144
  //#region source/config/lib/validate.ts
125
145
  const commerceAppConfigDomainsSchema = valibot.picklist(Object.keys(CommerceAppConfigSchemas));
@@ -243,6 +263,18 @@ Object.defineProperty(exports, 'hasMetadata', {
243
263
  return hasMetadata;
244
264
  }
245
265
  });
266
+ Object.defineProperty(exports, 'requiresInstallation', {
267
+ enumerable: true,
268
+ get: function () {
269
+ return requiresInstallation;
270
+ }
271
+ });
272
+ Object.defineProperty(exports, 'requiresInstallationFromDomains', {
273
+ enumerable: true,
274
+ get: function () {
275
+ return requiresInstallationFromDomains;
276
+ }
277
+ });
246
278
  Object.defineProperty(exports, 'validateCommerceAppConfig', {
247
279
  enumerable: true,
248
280
  get: function () {
@@ -0,0 +1,31 @@
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
+ import { n as CommerceAppConfig } from "../../app-DrYHK-z1.mjs";
16
+ import { RuntimeActionParams } from "@adobe/aio-commerce-lib-core/params";
17
+
18
+ //#region source/actions/app-config/router.d.ts
19
+ /** The arguments required to create the runtime action for the app-config action. */
20
+ type RuntimeActionFactoryArgs = {
21
+ appConfig: CommerceAppConfig;
22
+ };
23
+ //#endregion
24
+ //#region source/actions/app-config/index.d.ts
25
+ /**
26
+ * Factory to create the route handler for the `app-config` action.
27
+ * @param args - The arguments required to create the runtime action.
28
+ */
29
+ declare const appConfigRuntimeAction: (args: RuntimeActionFactoryArgs) => (params: RuntimeActionParams) => Promise<import("@adobe/aio-commerce-lib-core/responses").ActionResponse>;
30
+ //#endregion
31
+ export { appConfigRuntimeAction };
@@ -0,0 +1,199 @@
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
+ import { i as requiresInstallationFromDomains, o as getConfigDomains, t as validateCommerceAppConfig, u as hasBusinessConfigSchema } from "../../validate-Dfajrp99.mjs";
16
+ import { n as logger, t as HttpActionRouter } from "../../router-D58JJHHA.mjs";
17
+ import { resolveBusinessConfigSchema } from "@adobe/aio-commerce-lib-config";
18
+ import * as v from "valibot";
19
+ import { internalServerError, ok } from "@adobe/aio-commerce-lib-core/responses";
20
+ import { createHash } from "crypto";
21
+
22
+ //#region source/actions/app-config/openapi.ts
23
+ /**
24
+ * Loads the committed OpenAPI spec via dynamic import so it
25
+ * lands in its own chunk and is not parsed on every cold start.
26
+ */
27
+ const importOpenApi = () => import("../../openapi-B6uP0SRn.mjs");
28
+ /** Matches component schema `$ref` strings, capturing the schema name. */
29
+ const SCHEMA_REF_PATTERN = /"#\/components\/schemas\/(\w+)"/g;
30
+ /**
31
+ * Collects the names of every component schema referenced via `$ref` in a value
32
+ * Scans the serialized JSON, so it catches refs at any depth.
33
+ *
34
+ * @param value - Any part of the spec to scan.
35
+ */
36
+ function collectSchemaRefs(value) {
37
+ return [...(JSON.stringify(value) ?? "").matchAll(SCHEMA_REF_PATTERN)].map((match) => match[1]);
38
+ }
39
+ /**
40
+ * Deletes component schemas not reachable from the remaining paths, in place.
41
+ *
42
+ * Follows `$ref`s transitively from `spec.paths`; the visited set handles
43
+ * recursive schemas (e.g. `ScopeNode`).
44
+ *
45
+ * @param spec - The spec to prune, after paths have been stripped.
46
+ */
47
+ function pruneUnusedSchemas(spec) {
48
+ const schemas = spec.components.schemas;
49
+ const reachable = new Set(collectSchemaRefs(spec.paths));
50
+ const pending = [...reachable];
51
+ while (pending.length > 0) {
52
+ const name = pending.pop();
53
+ if (name === void 0) continue;
54
+ for (const ref of collectSchemaRefs(schemas[name])) if (!reachable.has(ref)) {
55
+ reachable.add(ref);
56
+ pending.push(ref);
57
+ }
58
+ }
59
+ for (const name of Object.keys(schemas)) if (!reachable.has(name)) delete schemas[name];
60
+ }
61
+ /**
62
+ * Removes top-level tags no longer referenced by any remaining path operation, in place.
63
+ * @param spec - The spec to prune, after paths have been stripped.
64
+ */
65
+ function pruneUnusedTags(spec) {
66
+ const usedTags = /* @__PURE__ */ new Set();
67
+ for (const pathItem of Object.values(spec.paths)) for (const operation of Object.values(pathItem)) for (const tag of operation.tags ?? []) usedTags.add(tag);
68
+ for (let i = spec.tags.length - 1; i >= 0; i--) if (!usedTags.has(spec.tags[i].name)) spec.tags.splice(i, 1);
69
+ }
70
+ /**
71
+ * Computes a short hash identifying the spec served for the given config domains.
72
+ * Changes whenever the served spec would: with the OpenAPI spec version (`info.version`),
73
+ * the package version, or the domains that drive pruning.
74
+ *
75
+ * @param domains - The active config domains.
76
+ */
77
+ function getOpenApiCacheKey(domains) {
78
+ const input = `1.7.0:${[...domains].sort().join(",")}:1.0.0`;
79
+ return createHash("sha256").update(input).digest("hex").slice(0, 8);
80
+ }
81
+ /** Returns the server URL to be set in the OpenAPI spec, based on the current namespace. */
82
+ function getServerUrl() {
83
+ return `https://${process.env.__OW_NAMESPACE}.adobeioruntime.net/api/v1/web/app-management`;
84
+ }
85
+ /**
86
+ * Builds the OpenAPI spec served by `GET /openapi.json`, tailored to the app's
87
+ * capabilities: unused paths are stripped, along with the schemas they leave
88
+ * unreferenced.
89
+ *
90
+ * Works on a fresh copy so the shared module import is never mutated. The
91
+ * committed `docs/openapi.json` always describes the full surface.
92
+ *
93
+ * @param domains - The active config domains that drive path trimming.
94
+ * @param logger - Logger used to report which paths get stripped.
95
+ */
96
+ async function buildOpenApiSpec(domains, logger) {
97
+ const { default: openAPISpec } = await importOpenApi();
98
+ const spec = structuredClone(openAPISpec);
99
+ const stripPath = (path) => {
100
+ if (spec.paths[path]) {
101
+ logger.debug(`Stripping OpenAPI spec path: ${path}`);
102
+ delete spec.paths[path];
103
+ }
104
+ };
105
+ if (!domains.has("businessConfig.schema")) {
106
+ logger.debug("Application doesn't define business configuration, stripping references...");
107
+ stripPath("/config");
108
+ stripPath("/scope-tree");
109
+ stripPath("/scope-tree/commerce");
110
+ }
111
+ if (!domains.has("adminUiSdk")) {
112
+ logger.debug("Application doesn't define Admin UI SDK registration, stripping references...");
113
+ stripPath("/registration");
114
+ }
115
+ if (!requiresInstallationFromDomains(domains)) {
116
+ logger.debug("Application doesn't require installation, stripping references...");
117
+ stripPath("/installation");
118
+ stripPath("/installation/validation");
119
+ stripPath("/installation/uninstallation");
120
+ }
121
+ pruneUnusedSchemas(spec);
122
+ pruneUnusedTags(spec);
123
+ spec.servers[0].url = getServerUrl();
124
+ return spec;
125
+ }
126
+
127
+ //#endregion
128
+ //#region source/actions/app-config/router.ts
129
+ /**
130
+ * App Config action router.
131
+ *
132
+ * Routes:
133
+ * - GET / Retrieve the Commerce App configuration.
134
+ * - GET /openapi.json Returns the OpenAPI spec for all SDK actions
135
+ */
136
+ const router = new HttpActionRouter().use(logger({ name: () => "app-config" }));
137
+ /** GET / - Get app config */
138
+ router.get("/", { handler: async (_req, { logger, rawParams }) => {
139
+ const rawAppConfig = rawParams.appConfig;
140
+ if (!rawAppConfig) return internalServerError("The app config is missing. Does the action receive it as a parameter?");
141
+ let appConfig = rawAppConfig;
142
+ if (hasBusinessConfigSchema(rawAppConfig)) {
143
+ logger.debug("Resolving business config schema...");
144
+ const schema = await resolveBusinessConfigSchema(rawAppConfig.businessConfig.schema, rawParams);
145
+ appConfig = {
146
+ ...rawAppConfig,
147
+ businessConfig: {
148
+ ...rawAppConfig.businessConfig,
149
+ schema
150
+ }
151
+ };
152
+ }
153
+ logger.debug("Validating app config...");
154
+ const config = validateCommerceAppConfig(appConfig);
155
+ logger.debug("Successfully validated the app config");
156
+ const domains = getConfigDomains(rawParams.appConfig);
157
+ const openApiSpecUrl = `${getServerUrl()}/app-config/openapi.json?ck=${getOpenApiCacheKey(domains)}`;
158
+ return ok({ body: {
159
+ ...config,
160
+ openApiSpecUrl
161
+ } });
162
+ } });
163
+ /**
164
+ * GET /openapi.json - Returns the OpenAPI spec for all SDK actions
165
+ * @internal - Do not add to OpenAPI Spec.
166
+ */
167
+ router.get("/openapi.json", {
168
+ query: v.object({ ck: v.optional(v.string()) }),
169
+ handler: async (req, { logger, rawParams }) => {
170
+ const { ck } = req.query;
171
+ const domains = getConfigDomains(rawParams.appConfig);
172
+ if (ck && getOpenApiCacheKey(domains) === ck) {
173
+ logger.debug(`Received request for OpenAPI spec with cache key query param: ${ck}`);
174
+ return ok({
175
+ body: await buildOpenApiSpec(domains, logger),
176
+ headers: { "Cache-Control": "public, max-age=31536000, immutable" }
177
+ });
178
+ }
179
+ return ok({ body: await buildOpenApiSpec(domains, logger) });
180
+ }
181
+ });
182
+
183
+ //#endregion
184
+ //#region source/actions/app-config/index.ts
185
+ /**
186
+ * Factory to create the route handler for the `app-config` action.
187
+ * @param args - The arguments required to create the runtime action.
188
+ */
189
+ const appConfigRuntimeAction = (args) => async (params) => {
190
+ const handler = router.handler();
191
+ const { appConfig } = args;
192
+ return await handler({
193
+ ...params,
194
+ appConfig
195
+ });
196
+ };
197
+
198
+ //#endregion
199
+ export { appConfigRuntimeAction };
@@ -12,17 +12,20 @@
12
12
  * governing permissions and limitations under the License.
13
13
  */
14
14
 
15
- import { RuntimeActionParams } from "@adobe/aio-commerce-lib-core/params";
16
15
  import { BusinessConfigSchema } from "@adobe/aio-commerce-lib-config";
16
+ import { RuntimeActionParams } from "@adobe/aio-commerce-lib-core/params";
17
17
 
18
- //#region source/actions/config.d.ts
19
- /** The arguments for the config action factory. */
18
+ //#region source/actions/config/router.d.ts
19
+ /** The arguments required to create the runtime action for the config action. */
20
20
  type ConfigActionFactoryArgs = {
21
21
  configSchema: BusinessConfigSchema;
22
22
  };
23
- /** Factory to create the route handler for the `config` action. */
24
- declare const configRuntimeAction: ({
25
- configSchema
26
- }: ConfigActionFactoryArgs) => (params: RuntimeActionParams) => Promise<import("@adobe/aio-commerce-lib-core/responses").ActionResponse>;
23
+ //#endregion
24
+ //#region source/actions/config/index.d.ts
25
+ /**
26
+ * Factory to create the route handler for the `config` action.
27
+ * @param args - The arguments required to create the runtime action.
28
+ */
29
+ declare const configRuntimeAction: (args: ConfigActionFactoryArgs) => (params: RuntimeActionParams) => Promise<import("@adobe/aio-commerce-lib-core/responses").ActionResponse>;
27
30
  //#endregion
28
31
  export { configRuntimeAction };
@@ -12,20 +12,50 @@
12
12
  * governing permissions and limitations under the License.
13
13
  */
14
14
 
15
- import { n as logger, t as HttpActionRouter } from "../router-D58JJHHA.mjs";
16
- import { r as nonEmptyStringValueSchema } from "../schemas-hRovglBF.mjs";
15
+ import { r as nonEmptyStringValueSchema } from "../../schemas-hRovglBF.mjs";
16
+ import { n as logger, t as HttpActionRouter } from "../../router-D58JJHHA.mjs";
17
17
  import { byScopeId, getConfiguration, initialize, setConfiguration } from "@adobe/aio-commerce-lib-config";
18
- import { ok } from "@adobe/aio-commerce-lib-core/responses";
19
18
  import * as v from "valibot";
19
+ import { ok } from "@adobe/aio-commerce-lib-core/responses";
20
20
 
21
- //#region source/actions/config.ts
22
- const MASKED_PASSWORD_VALUE = "*****";
21
+ //#region source/actions/config/schema.ts
22
+ const AcceptedConfigurationValuesSchema = v.union([
23
+ v.boolean(),
24
+ v.string(),
25
+ v.array(v.string())
26
+ ]);
23
27
  /** The set of valid Commerce environments a configuration field can be scoped to. */
24
28
  const COMMERCE_ENVS = ["paas", "saas"];
29
+ /** Query parameters for GET / */
30
+ const GetConfigurationQuerySchema = v.object({
31
+ scopeId: nonEmptyStringValueSchema("scopeId"),
32
+ commerceEnv: v.optional(v.picklist(COMMERCE_ENVS))
33
+ });
34
+ /** Request body for PUT / */
35
+ const PutConfigBodySchema = v.object({
36
+ scopeId: nonEmptyStringValueSchema("scopeId"),
37
+ config: v.array(v.object({
38
+ name: nonEmptyStringValueSchema("config[i].name"),
39
+ value: v.union([v.string(), v.array(v.string())])
40
+ }))
41
+ });
42
+ /** Request body for PATCH / */
43
+ const PatchConfigBodySchema = v.object({
44
+ scopeId: nonEmptyStringValueSchema("scopeId"),
45
+ config: v.array(v.object({
46
+ name: nonEmptyStringValueSchema("config[i].name"),
47
+ value: v.nullable(AcceptedConfigurationValuesSchema)
48
+ }))
49
+ });
50
+
51
+ //#endregion
52
+ //#region source/actions/config/router.ts
53
+ const MASKED_PASSWORD_VALUE = "*****";
25
54
  /**
26
55
  * Filters a business configuration schema to the fields applicable to the
27
56
  * given Commerce environment. Fields without an `env` property apply to all
28
57
  * environments and are always included.
58
+ *
29
59
  * @param schema - The business configuration schema to filter.
30
60
  * @param env - The Commerce environment to filter by.
31
61
  */
@@ -34,9 +64,9 @@ function filterSchemaByEnv(schema, env) {
34
64
  }
35
65
  /**
36
66
  * Filters password fields from the configuration values.
67
+ *
37
68
  * @param schema - The schema to use to filter the values.
38
69
  * @param values - The values to filter.
39
- * @returns The filtered values.
40
70
  */
41
71
  function filterPasswordFields(schema, values) {
42
72
  return values.map((item) => {
@@ -47,13 +77,18 @@ function filterPasswordFields(schema, values) {
47
77
  return item;
48
78
  });
49
79
  }
50
- const router = new HttpActionRouter().use(logger());
80
+ /**
81
+ * Config action router.
82
+ *
83
+ * Routes:
84
+ * - GET / Get current configuration values for a given scope
85
+ * - POST / Set configuration (overrides all values for the scope) (deprecated)
86
+ * - PATCH / Partially update configuration (only updates provided fields, allows unsetting)
87
+ */
88
+ const router = new HttpActionRouter().use(logger({ name: () => "config" }));
51
89
  /** GET / - Retrieve configuration */
52
90
  router.get("/", {
53
- query: v.object({
54
- scopeId: nonEmptyStringValueSchema("scopeId"),
55
- commerceEnv: v.optional(v.picklist(COMMERCE_ENVS))
56
- }),
91
+ query: GetConfigurationQuerySchema,
57
92
  handler: async (req, ctx) => {
58
93
  const { logger, rawParams } = ctx;
59
94
  const { configSchema: rawConfigSchema } = rawParams;
@@ -77,17 +112,12 @@ router.get("/", {
77
112
  });
78
113
  /**
79
114
  * PUT / - Set configuration (deprecated)
115
+ *
80
116
  * @deprecated Use PATCH instead. This endpoint overwrites all values for the scope
81
117
  * and does not support partial updates or unset semantics.
82
118
  */
83
119
  router.put("/", {
84
- body: v.object({
85
- scopeId: nonEmptyStringValueSchema("scopeId"),
86
- config: v.array(v.object({
87
- name: nonEmptyStringValueSchema("config.name"),
88
- value: v.union([v.string(), v.array(v.string())])
89
- }))
90
- }),
120
+ body: PutConfigBodySchema,
91
121
  handler: async (req, ctx) => {
92
122
  const { logger, rawParams } = ctx;
93
123
  logger.debug(`Setting configuration with scope id: ${req.body.scopeId}`);
@@ -109,17 +139,7 @@ router.put("/", {
109
139
  });
110
140
  /** PATCH / - Partially update configuration */
111
141
  router.patch("/", {
112
- body: v.object({
113
- scopeId: nonEmptyStringValueSchema("scopeId"),
114
- config: v.array(v.object({
115
- name: nonEmptyStringValueSchema("config.name"),
116
- value: v.nullable(v.union([
117
- v.boolean(),
118
- v.string(),
119
- v.array(v.string())
120
- ]))
121
- }))
122
- }),
142
+ body: PatchConfigBodySchema,
123
143
  handler: async (req, ctx) => {
124
144
  const { logger, rawParams } = ctx;
125
145
  logger.debug(`Patching configuration with scope id: ${req.body.scopeId}`);
@@ -136,9 +156,17 @@ router.patch("/", {
136
156
  });
137
157
  }
138
158
  });
139
- /** Factory to create the route handler for the `config` action. */
140
- const configRuntimeAction = ({ configSchema }) => async (params) => {
141
- return await router.handler()({
159
+
160
+ //#endregion
161
+ //#region source/actions/config/index.ts
162
+ /**
163
+ * Factory to create the route handler for the `config` action.
164
+ * @param args - The arguments required to create the runtime action.
165
+ */
166
+ const configRuntimeAction = (args) => async (params) => {
167
+ const handler = router.handler();
168
+ const { configSchema } = args;
169
+ return await handler({
142
170
  ...params,
143
171
  configSchema
144
172
  });
@@ -12,21 +12,23 @@
12
12
  * governing permissions and limitations under the License.
13
13
  */
14
14
 
15
- import { n as CommerceAppConfigOutputModel, t as CommerceAppConfig } from "../app-CakwxQvs.cjs";
16
- import { o as InstallationContext } from "../step-CKVE0aJi.cjs";
15
+ import { n as CommerceAppConfig, r as CommerceAppConfigOutputModel } from "../../app-DrYHK-z1.mjs";
16
+ import { Y as InstallationContext } from "../../index-DLMbTtKS.mjs";
17
17
  import { RuntimeActionParams } from "@adobe/aio-commerce-lib-core/params";
18
18
 
19
- //#region source/actions/installation.d.ts
19
+ //#region source/actions/installation/router.d.ts
20
20
  type CustomScriptsLoader = (config: CommerceAppConfigOutputModel, logger: InstallationContext["logger"]) => Record<string, unknown>;
21
21
  /** Arguments for the runtime action factory. */
22
22
  type RuntimeActionFactoryArgs = {
23
23
  appConfig: CommerceAppConfig;
24
24
  customScriptsLoader?: CustomScriptsLoader;
25
25
  };
26
- /** Factory to create the route handler for the `installation` action. */
27
- declare const installationRuntimeAction: ({
28
- appConfig,
29
- customScriptsLoader
30
- }: RuntimeActionFactoryArgs) => (params: RuntimeActionParams) => Promise<import("@adobe/aio-commerce-lib-core/responses").ActionResponse>;
26
+ //#endregion
27
+ //#region source/actions/installation/index.d.ts
28
+ /**
29
+ * Factory to create the route handler for the `installation` action.
30
+ * @param args - The arguments required to create the runtime action.
31
+ */
32
+ declare const installationRuntimeAction: (args: RuntimeActionFactoryArgs) => (params: RuntimeActionParams) => Promise<import("@adobe/aio-commerce-lib-core/responses").ActionResponse>;
31
33
  //#endregion
32
34
  export { installationRuntimeAction };
@@ -12,13 +12,12 @@
12
12
  * governing permissions and limitations under the License.
13
13
  */
14
14
 
15
- import { n as logger, t as HttpActionRouter } from "../router-D58JJHHA.mjs";
16
- import { r as nonEmptyStringValueSchema } from "../schemas-hRovglBF.mjs";
17
- import { t as validateCommerceAppConfig } from "../validate-Du3LhCre.mjs";
18
- 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-BZ4Y6lVp.mjs";
19
- import { accepted, badRequest, conflict, internalServerError, noContent, ok } from "@adobe/aio-commerce-lib-core/responses";
15
+ import { r as nonEmptyStringValueSchema } from "../../schemas-hRovglBF.mjs";
16
+ 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-BUX-w2Ji.mjs";
17
+ import { t as validateCommerceAppConfig } from "../../validate-Dfajrp99.mjs";
18
+ import { n as logger, t as HttpActionRouter } from "../../router-D58JJHHA.mjs";
20
19
  import * as v from "valibot";
21
- import { object, string } from "valibot";
20
+ import { accepted, badRequest, conflict, internalServerError, noContent, ok } from "@adobe/aio-commerce-lib-core/responses";
22
21
  import { init } from "@adobe/aio-lib-files";
23
22
  import { init as init$1 } from "@adobe/aio-lib-state";
24
23
  import openwhisk from "openwhisk";
@@ -257,16 +256,19 @@ const AppDataSchema = v.object({
257
256
  });
258
257
 
259
258
  //#endregion
260
- //#region source/actions/installation.ts
261
- const DEFAULT_ACTION_NAME = "app-management/installation";
262
- /** Request body schema shared by POST / and POST /validation. */
263
- const InstallationRequestBodySchema = object({
259
+ //#region source/actions/installation/schema.ts
260
+ /** Request body for POST / and POST /validation (shared shape) */
261
+ const InstallationRequestBodySchema = v.object({
264
262
  appData: AppDataSchema,
265
- commerceBaseUrl: string(),
266
- commerceEnv: string(),
267
- ioEventsUrl: string(),
268
- ioEventsEnv: string()
263
+ commerceBaseUrl: v.string(),
264
+ commerceEnv: v.string(),
265
+ ioEventsUrl: v.string(),
266
+ ioEventsEnv: v.string()
269
267
  });
268
+
269
+ //#endregion
270
+ //#region source/actions/installation/router.ts
271
+ const DEFAULT_ACTION_NAME = "app-management/installation";
270
272
  /** Creates a workflow state store with the given prefix. */
271
273
  function createWorkflowStore(prefix) {
272
274
  return createCombinedStore({
@@ -349,14 +351,14 @@ function createInstallationHooks(store, logFn) {
349
351
  * Installation action router.
350
352
  *
351
353
  * Routes:
352
- * - GET /installation - Get current installation status
353
- * - POST /installation - Start installation (creates plan, invokes execution async)
354
- * - POST /installation/execution - Execute installation (internal, called async)
355
- * - POST /installation/validation - Pre-installation validation
356
- * - POST /installation/uninstallation - Start uninstallation (async)
357
- * - GET /installation/uninstallation - Get current uninstallation status
358
- * - POST /installation/uninstallation/execution - Execute uninstallation (internal, called async)
359
- * - DELETE /installation/uninstallation - Clear uninstallation state only (no offboarding)
354
+ * - GET / Get current installation status
355
+ * - POST / Start installation (creates plan, invokes execution async)
356
+ * - POST /execution Execute installation (internal, called async)
357
+ * - POST /validation Pre-installation validation
358
+ * - POST /uninstallation Start uninstallation (creates plan, invokes execution async)
359
+ * - GET /uninstallation Get current uninstallation status
360
+ * - POST /uninstallation/execution Execute uninstallation (internal, called async)
361
+ * - DELETE /uninstallation Clear uninstallation state only (no offboarding)
360
362
  */
361
363
  const router = new HttpActionRouter().use(logger({ name: () => "installation" }));
362
364
  /**
@@ -398,7 +400,7 @@ router.post("/", {
398
400
  logger.debug("Previous installation failed, allowing retry");
399
401
  }
400
402
  const rawAppConfig = rawParams.appConfig;
401
- if (!rawAppConfig) return internalServerError("Could not find or parse the app.commerce.manifest.json file, is it present and valid?");
403
+ if (!rawAppConfig) return internalServerError("The app config is missing. Does the action receive it as a parameter?");
402
404
  const appConfig = validateCommerceAppConfig(rawAppConfig);
403
405
  const initialState = createInitialInstallationState({ config: appConfig });
404
406
  logger.debug(`Created initial state: ${initialState.id}`);
@@ -426,7 +428,8 @@ router.post("/", {
426
428
  }
427
429
  });
428
430
  /**
429
- * POST /installation/execution - Execute installation (internal)
431
+ * POST /installation/execution - Execute installation
432
+ * @internal - Do not add to OpenAPI Spec.
430
433
  *
431
434
  * This endpoint is called asynchronously by POST /installation.
432
435
  * It runs the actual installation workflow and saves state.
@@ -473,7 +476,7 @@ router.post("/validation", {
473
476
  handler: async (req, { logger, rawParams }) => {
474
477
  logger.debug("Running pre-installation validation...");
475
478
  const rawAppConfig = rawParams.appConfig;
476
- if (!rawAppConfig) return internalServerError("Could not find or parse the app.commerce.manifest.json file, is it present and valid?");
479
+ if (!rawAppConfig) return internalServerError("The app config is missing. Does the action receive it as a parameter?");
477
480
  const appConfig = validateCommerceAppConfig(rawAppConfig);
478
481
  const { appData, ...params } = buildWorkflowParams(req.body, rawParams);
479
482
  const result = await runValidation({
@@ -513,7 +516,7 @@ router.post("/uninstallation", {
513
516
  const { appData, commerceBaseUrl } = req.body;
514
517
  logger.debug(`Starting uninstallation for app "${appData.projectName}" (workspace: "${appData.workspaceName}", commerce: "${commerceBaseUrl}")`);
515
518
  const rawAppConfig = rawParams.appConfig;
516
- if (!rawAppConfig) return internalServerError("Could not find or parse the app.commerce.manifest.json file, is it present and valid?");
519
+ if (!rawAppConfig) return internalServerError("The app config is missing. Does the action receive it as a parameter?");
517
520
  const appConfig = validateCommerceAppConfig(rawAppConfig);
518
521
  const store = await createUninstallationStore();
519
522
  const existingState = await store.get(getStorageKey());
@@ -546,7 +549,8 @@ router.post("/uninstallation", {
546
549
  }
547
550
  });
548
551
  /**
549
- * POST /uninstallation/execution - Execute uninstallation (internal, called async by POST /uninstallation)
552
+ * POST /uninstallation/execution - Execute uninstallation
553
+ * @internal - Do not add to OpenAPI Spec.
550
554
  *
551
555
  * Flow:
552
556
  * 1. Build InstallationContext from params
@@ -595,9 +599,17 @@ router.delete("/uninstallation", { handler: async (_req, { logger }) => {
595
599
  logger.debug("Uninstallation state cleared");
596
600
  return noContent();
597
601
  } });
598
- /** Factory to create the route handler for the `installation` action. */
599
- const installationRuntimeAction = ({ appConfig, customScriptsLoader }) => async (params) => {
600
- return await router.handler()({
602
+
603
+ //#endregion
604
+ //#region source/actions/installation/index.ts
605
+ /**
606
+ * Factory to create the route handler for the `installation` action.
607
+ * @param args - The arguments required to create the runtime action.
608
+ */
609
+ const installationRuntimeAction = (args) => async (params) => {
610
+ const handler = router.handler();
611
+ const { appConfig, customScriptsLoader } = args;
612
+ return await handler({
601
613
  ...params,
602
614
  appConfig,
603
615
  customScriptsLoader