@adobe/aio-commerce-lib-app 1.5.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 (67) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/dist/cjs/actions/app-config/index.cjs +202 -0
  3. package/dist/cjs/actions/{app-config.d.cts → app-config/index.d.cts} +11 -9
  4. package/dist/cjs/actions/{config.cjs → config/index.cjs} +79 -46
  5. package/dist/{es/actions/config.d.mts → cjs/actions/config/index.d.cts} +10 -8
  6. package/dist/cjs/actions/{installation.cjs → installation/index.cjs} +55 -36
  7. package/dist/{es/actions/installation.d.mts → cjs/actions/installation/index.d.cts} +11 -10
  8. package/dist/cjs/actions/{registration.cjs → registration/index.cjs} +16 -7
  9. package/dist/cjs/actions/{registration.d.cts → registration/index.d.cts} +8 -9
  10. package/dist/cjs/actions/{scope-tree.cjs → scope-tree/index.cjs} +52 -15
  11. package/dist/{es/actions/scope-tree.d.mts → cjs/actions/scope-tree/index.d.cts} +2 -5
  12. package/dist/cjs/{admin-ui-sdk-BiSopnKI.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 +241 -56
  15. package/dist/cjs/commands/templates/app-management/app-config.js.template +2 -2
  16. package/dist/cjs/config/index.cjs +3 -3
  17. package/dist/cjs/config/index.d.cts +181 -1158
  18. package/dist/cjs/{config-ct-qMOGj.cjs → config-D-s0GSep.cjs} +4 -6
  19. package/dist/cjs/{error-C5LNOZ4f.cjs → error-D-N0PKSl.cjs} +0 -1
  20. package/dist/cjs/{index-B5WKJ3hJ.d.cts → index-B5gJ-q4U.d.cts} +172 -3
  21. package/dist/cjs/index-BXm8UbK7.d.cts +16 -0
  22. package/dist/cjs/{logging-BTevALnL.cjs → logging-BVz3weoC.cjs} +1 -1
  23. package/dist/cjs/management/index.cjs +1 -1
  24. package/dist/cjs/management/index.d.cts +2 -3
  25. package/dist/cjs/{management-D1QXg4YU.cjs → management-Dehz9qSJ.cjs} +114 -51
  26. package/dist/cjs/openapi-Cux6K4ZD.cjs +3072 -0
  27. package/dist/cjs/{router-CFErodHU.cjs → router-BOR7T6qR.cjs} +1 -1
  28. package/dist/cjs/{schemas-CukVpc19.cjs → schemas-FngDuIeo.cjs} +1 -1
  29. package/dist/cjs/{validate-b_bI4mDb.cjs → validate-oAOpyFyb.cjs} +49 -17
  30. package/dist/cjs/{webhooks-DS1BtgED.cjs → webhooks-tbZy9G3p.cjs} +4 -4
  31. package/dist/es/actions/{app-config.d.mts → app-config/index.d.mts} +11 -9
  32. package/dist/es/actions/app-config/index.mjs +199 -0
  33. package/dist/{cjs/actions/config.d.cts → es/actions/config/index.d.mts} +10 -8
  34. package/dist/es/actions/{config.mjs → config/index.mjs} +78 -45
  35. package/dist/{cjs/actions/installation.d.cts → es/actions/installation/index.d.mts} +11 -10
  36. package/dist/es/actions/{installation.mjs → installation/index.mjs} +54 -36
  37. package/dist/es/actions/{registration.d.mts → registration/index.d.mts} +8 -9
  38. package/dist/es/actions/{registration.mjs → registration/index.mjs} +16 -6
  39. package/dist/{cjs/actions/scope-tree.d.cts → es/actions/scope-tree/index.d.mts} +2 -5
  40. package/dist/es/actions/{scope-tree.mjs → scope-tree/index.mjs} +51 -14
  41. package/dist/es/{admin-ui-sdk-CCo2SWiL.d.mts → admin-ui-sdk-BwnD0xjK.d.mts} +6 -9
  42. package/dist/es/app-DrYHK-z1.d.mts +1629 -0
  43. package/dist/es/commands/index.mjs +223 -38
  44. package/dist/es/commands/templates/app-management/app-config.js.template +2 -2
  45. package/dist/es/config/index.d.mts +181 -1157
  46. package/dist/es/config/index.mjs +3 -3
  47. package/dist/es/{config-DGPFTk6w.mjs → config-3I4eLyyR.mjs} +4 -5
  48. package/dist/es/index-B0XqHwY5.d.mts +16 -0
  49. package/dist/es/{index-CCov0odd.d.mts → index-DLMbTtKS.d.mts} +172 -3
  50. package/dist/es/management/index.d.mts +2 -3
  51. package/dist/es/management/index.mjs +1 -1
  52. package/dist/es/{management-CCsOfniv.mjs → management-BUX-w2Ji.mjs} +113 -51
  53. package/dist/es/openapi-B6uP0SRn.mjs +3024 -0
  54. package/dist/es/{validate-Dn3lLTGj.mjs → validate-Dfajrp99.mjs} +37 -17
  55. package/dist/es/{webhooks-Dhrkkip7.mjs → webhooks-B5oq9ULL.mjs} +3 -3
  56. package/package.json +29 -17
  57. package/dist/cjs/actions/app-config.cjs +0 -41
  58. package/dist/cjs/app-C6kImBl7.d.cts +0 -564
  59. package/dist/cjs/step-CWYnKbga.d.cts +0 -187
  60. package/dist/es/actions/app-config.mjs +0 -39
  61. package/dist/es/app-DcY6dJiQ.d.mts +0 -564
  62. package/dist/es/step-0eI2x4C9.d.mts +0 -187
  63. /package/dist/cjs/{chunk-DS2yp5vX.cjs → chunk-Cozy-1ZF.cjs} +0 -0
  64. /package/dist/es/{error-DHlYzkbb.mjs → error-_RMwtrUA.mjs} +0 -0
  65. /package/dist/es/{logging-XIUXDK5T.mjs → logging-DbJHXSKh.mjs} +0 -0
  66. /package/dist/es/{router-BxaxEEu3.mjs → router-D58JJHHA.mjs} +0 -0
  67. /package/dist/es/{schemas-DOcnD16x.mjs → schemas-hRovglBF.mjs} +0 -0
@@ -13,26 +13,28 @@
13
13
  * governing permissions and limitations under the License.
14
14
  */
15
15
 
16
- import { a as hasCustomInstallationSteps, d as hasAdminUiSdk } from "../webhooks-Dhrkkip7.mjs";
17
- import { c as hasBusinessConfigSchema, i as getConfigDomains, t as validateCommerceAppConfig } from "../validate-Dn3lLTGj.mjs";
18
- import { a as getExecCommand, c as isESM, i as detectPackageManager, l as makeOutputDirFor, n as readCommerceAppConfig, o as getInstallCommand, s as getProjectRootDirectory, t as parseCommerceAppConfig, u as readPackageJson } from "../config-DGPFTk6w.mjs";
19
- import { t as stringifyError } from "../error-DHlYzkbb.mjs";
20
- import { t as inspect } from "../logging-XIUXDK5T.mjs";
16
+ import { t as stringifyError } from "../error-_RMwtrUA.mjs";
17
+ import { a as getExecCommand, c as isESM, i as detectPackageManager, l as makeOutputDirFor, n as readCommerceAppConfig, o as getInstallCommand, r as resolveCommerceAppConfig, s as getProjectRootDirectory, t as parseCommerceAppConfig, u as readPackageJson } from "../config-3I4eLyyR.mjs";
18
+ import { a as hasCustomInstallationSteps, d as hasAdminUiSdk } from "../webhooks-B5oq9ULL.mjs";
19
+ import { o as getConfigDomains, r as requiresInstallation, t as validateCommerceAppConfig, u as hasBusinessConfigSchema } from "../validate-Dfajrp99.mjs";
20
+ import { t as inspect } from "../logging-DbJHXSKh.mjs";
21
21
  import { CommerceSdkValidationError } from "@adobe/aio-commerce-lib-core/error";
22
- import path, { basename, dirname, join, relative, resolve } from "path";
23
- import { existsSync, readFileSync, writeFileSync } from "fs";
24
- import { readFile, writeFile } from "fs/promises";
25
22
  import consola, { consola as consola$1 } from "consola";
23
+ import path, { basename, dirname, extname, join, relative, resolve, sep } from "path";
24
+ import { hasDynamicSchema } from "@adobe/aio-commerce-lib-config";
26
25
  import * as prettier from "prettier";
26
+ import { existsSync, readFileSync, writeFileSync } from "fs";
27
+ import { access, readFile, rm, writeFile } from "fs/promises";
27
28
  import { fileURLToPath } from "url";
28
- import { Document, YAMLMap, YAMLSeq, isMap, isSeq, parseDocument } from "yaml";
29
+ import { Document, YAMLMap, YAMLSeq, isMap, isPair, isSeq, parseDocument } from "yaml";
30
+ import NpmPackageJson from "@npmcli/package-json";
29
31
  import { colorize, formatTree } from "consola/utils";
32
+ import { build } from "esbuild";
30
33
  import stringify, { stringify as stringify$1 } from "safe-stable-stringify";
31
34
  import { execSync, spawnSync } from "child_process";
32
35
  import config from "@adobe/aio-lib-core-config";
33
36
  import aioIms from "@adobe/aio-lib-ims";
34
37
  import dotenv from "dotenv";
35
- import NpmPackageJson from "@npmcli/package-json";
36
38
 
37
39
  //#region source/commands/constants.ts
38
40
  /** The name of the package containing all the generated runtime actions */
@@ -55,6 +57,10 @@ const ADMIN_UI_SDK_PACKAGE_NAME = "admin-ui-sdk";
55
57
  const ADMIN_UI_SDK_ACTIONS_PATH = `${GENERATED_PATH}/actions/registration`;
56
58
  /** The name of the configuration schema file */
57
59
  const APP_MANIFEST_FILE = "app.commerce.manifest.json";
60
+ /** The name of the generated runtime-safe app config module (dynamic schemas only). */
61
+ const RUNTIME_APP_CONFIG_FILE = "app.commerce.config.js";
62
+ /** Package import alias for the generated runtime-safe app config module. */
63
+ const APP_CONFIG_IMPORT_ALIAS = "#app.commerce.config";
58
64
  /** The name of the commerce app configuration file */
59
65
  const COMMERCE_APP_CONFIG_FILE = "app.commerce.config";
60
66
  /** The name of the configuration schema file */
@@ -94,6 +100,14 @@ async function loadAppManifest() {
94
100
  return appConfig;
95
101
  }
96
102
  /**
103
+ * Whether the app config contains anything that can't be JSON-serialized as-is
104
+ * and therefore requires generating a runtime-safe ESM config module.
105
+ */
106
+ function hasDynamicAppConfig(appConfig) {
107
+ const schema = appConfig.businessConfig?.schema;
108
+ return Array.isArray(schema) && hasDynamicSchema(schema);
109
+ }
110
+ /**
97
111
  * Path to an extension point's `.generated` directory, relative to the project root.
98
112
  * @param extensionPointId - The extension point ID, e.g. "commerce/extensibility/1"
99
113
  */
@@ -136,6 +150,21 @@ function getAdminUiSdkActionsDir(extensionPointId) {
136
150
  function getAdminUiSdkRegistrationActionPath(extensionPointId) {
137
151
  return join(getAdminUiSdkActionsDir(extensionPointId), "index.js");
138
152
  }
153
+ /** Path to the generated app manifest JSON file, relative to the project root. */
154
+ function getManifestPath() {
155
+ return join(getGeneratedDir(EXTENSIBILITY_EXTENSION_POINT_ID), APP_MANIFEST_FILE);
156
+ }
157
+ /**
158
+ * Path to the generated runtime-safe app config ESM module, relative to the
159
+ * project root. Used when the business config schema contains dynamic options.
160
+ */
161
+ function getRuntimeAppConfigPath() {
162
+ return join(getGeneratedDir(EXTENSIBILITY_EXTENSION_POINT_ID), RUNTIME_APP_CONFIG_FILE);
163
+ }
164
+ /** Path to the generated configuration schema file, relative to the project root. */
165
+ function getSchemaPath() {
166
+ return join(getGeneratedDir(CONFIGURATION_EXTENSION_POINT_ID), CONFIG_SCHEMA_FILE_NAME);
167
+ }
139
168
 
140
169
  //#endregion
141
170
  //#region source/commands/generate/actions/config.ts
@@ -164,7 +193,7 @@ function createActionDefinition(actionName, config = {}, options = {}) {
164
193
  ...options,
165
194
  function: `${GENERATED_ACTIONS_PATH}/${actionName}.js`,
166
195
  web: options.web ?? "yes",
167
- runtime: "nodejs:22",
196
+ runtime: "nodejs:24",
168
197
  annotations: {
169
198
  "require-adobe-auth": true,
170
199
  final: true
@@ -191,8 +220,6 @@ function getRuntimeActions(extConfig, dir) {
191
220
  * @param features - The features that are enabled for the app.
192
221
  */
193
222
  function buildAppManagementExtConfig(appConfig) {
194
- const features = getConfigDomains(appConfig);
195
- const hasPasswordFieldsInSchema = hasBusinessConfigSchema(appConfig) && appConfig.businessConfig.schema.some((field) => field.type === "password");
196
223
  const extConfig = {
197
224
  hooks: { "pre-app-build": "EXTENSION=extensibility/1 $packageExec aio-commerce-lib-app hooks pre-app-build" },
198
225
  operations: { workerProcess: [{
@@ -204,13 +231,9 @@ function buildAppManagementExtConfig(appConfig) {
204
231
  actions: { "app-config": createActionDefinition("app-config") }
205
232
  } } }
206
233
  };
207
- if ([
208
- "installation.customInstallationSteps",
209
- "eventing.commerce",
210
- "eventing.external",
211
- "webhooks",
212
- "adminUiSdk"
213
- ].some((feature) => features.has(feature))) {
234
+ const needsInstallAction = requiresInstallation(appConfig);
235
+ const hasPasswordFieldsInSchema = hasBusinessConfigSchema(appConfig) && appConfig.businessConfig.schema.some((field) => field.type === "password");
236
+ if (needsInstallAction) {
214
237
  extConfig.operations.workerProcess.push({
215
238
  type: "action",
216
239
  impl: `${PACKAGE_NAME}/installation`
@@ -263,7 +286,7 @@ function buildAdminUiSdkExtConfig() {
263
286
  actions: { registration: {
264
287
  function: `${ADMIN_UI_SDK_ACTIONS_PATH}/index.js`,
265
288
  web: "yes",
266
- runtime: "nodejs:22",
289
+ runtime: "nodejs:24",
267
290
  annotations: {
268
291
  "require-adobe-auth": true,
269
292
  final: true
@@ -337,6 +360,33 @@ function getOrCreateMap(doc, path, options) {
337
360
  typeName: "map"
338
361
  });
339
362
  }
363
+ /**
364
+ * Read the `inputs` map from an existing YAML action definition into a plain
365
+ * object. Used by codegen to merge developer-added inputs with the ones the
366
+ * generator manages, so regeneration does not strip user-added entries.
367
+ *
368
+ * @param existingAction - The YAML map representing the existing action.
369
+ */
370
+ function getExistingInputs(existingAction) {
371
+ const inputs = existingAction?.get("inputs");
372
+ if (!isMap(inputs)) return {};
373
+ return Object.fromEntries(inputs.items.map((item) => {
374
+ if (!isPair(item)) return [];
375
+ return [String(item.key), item.value];
376
+ }));
377
+ }
378
+ /**
379
+ * Read a string field from an existing YAML action definition. Used by codegen
380
+ * to preserve developer-set values (e.g. `runtime`) across regeneration
381
+ * instead of overwriting them.
382
+ *
383
+ * @param key - The field to read.
384
+ * @param existingAction - The YAML map representing the existing action.
385
+ */
386
+ function getExistingString(key, existingAction) {
387
+ const value = existingAction?.get(key);
388
+ return typeof value === "string" ? value : void 0;
389
+ }
340
390
 
341
391
  //#endregion
342
392
  //#region ../../packages-private/scripting-utils/source/yaml/codegen.ts
@@ -365,19 +415,30 @@ function buildWeb(extConfig, web) {
365
415
  if (!extConfig.hasIn(["web"])) extConfig.add(extConfig.createPair("web", web));
366
416
  }
367
417
  /**
368
- * Build the definition for a runtime action
369
- * @param name - The name of the action
370
- * @param path - The path where the action is located
371
- * @param action - The action definition
418
+ * Build the definition for a runtime action.
419
+ *
420
+ * Developer-added `inputs` keys (anything not in the generator-managed set) on
421
+ * `existingAction` are preserved so that hand-written entries for example
422
+ * factory credentials for `dynamicList` fields — survive regeneration.
423
+ *
424
+ * A `runtime` already set on `existingAction` is likewise preserved, so a
425
+ * developer can pin a different Node runtime (e.g. `nodejs:24`) in
426
+ * `ext.config.yaml` once without codegen reverting it on the next run.
427
+ *
428
+ * @param action - The action definition to build.
429
+ * @param existingAction - The action's previous YAML definition, if any.
372
430
  */
373
- function buildActionDefinition(action) {
431
+ function buildActionDefinition(action, existingAction) {
374
432
  const actionDef = new YAMLMap();
375
- const inputs = { LOG_LEVEL: "$LOG_LEVEL" };
433
+ const existingInputs = getExistingInputs(existingAction);
434
+ const existingRuntime = getExistingString("runtime", existingAction);
435
+ const managedInputs = { LOG_LEVEL: "$LOG_LEVEL" };
376
436
  actionDef.set("function", action.function);
377
437
  actionDef.set("web", action.web ?? "yes");
378
- actionDef.set("runtime", action.runtime ?? "nodejs:22");
438
+ actionDef.set("runtime", existingRuntime ?? action.runtime ?? "nodejs:24");
379
439
  actionDef.set("inputs", {
380
- ...inputs,
440
+ ...existingInputs,
441
+ ...managedInputs,
381
442
  ...action.inputs ?? {}
382
443
  });
383
444
  actionDef.set("annotations", { ...action.annotations ?? {
@@ -452,11 +513,13 @@ function buildRuntimeManifest(extConfig, manifest) {
452
513
  ], { onBeforeCreate: (pair) => {
453
514
  pair.key.commentBefore = " This package definition is auto-generated. Do not remove or manually edit.";
454
515
  } });
516
+ const existingActions = packageDef.get("actions");
455
517
  const actions = new YAMLMap();
456
518
  packageDef.set("license", pkg.license ?? "Apache-2.0");
457
519
  packageDef.set("actions", actions);
458
520
  for (const [actionName, action] of Object.entries(pkg.actions ?? {})) {
459
- const actionDef = buildActionDefinition(action);
521
+ const existingAction = isMap(existingActions) ? existingActions.get(actionName) : void 0;
522
+ const actionDef = buildActionDefinition(action, isMap(existingAction) ? existingAction : void 0);
460
523
  actions.set(actionName, actionDef);
461
524
  }
462
525
  }
@@ -499,6 +562,109 @@ async function writeExtConfig(configPath, doc) {
499
562
  const __dirname = dirname(fileURLToPath(import.meta.url));
500
563
  /** The path to the action templates directory, sibling to this file. */
501
564
  const TEMPLATES_DIR = join(__dirname, "templates");
565
+ const TYPESCRIPT_CONFIG_EXTENSIONS = new Set([
566
+ ".ts",
567
+ ".mts",
568
+ ".cts"
569
+ ]);
570
+ const LEADING_DOT_SLASH_PATTERN = /^\.\//u;
571
+ const DYNAMIC_APP_CONFIG_IMPORT = `import appConfig from "${APP_CONFIG_IMPORT_ALIAS}";`;
572
+ const STATIC_APP_MANIFEST_IMPORT = "import appConfig from \"../../app.commerce.manifest.json\" with { type: \"json\" };";
573
+ const STATIC_CONFIG_SCHEMA_IMPORT = "import configSchema from \"../../configuration-schema.json\" with { type: \"json\" };";
574
+ /** Normalize a path for use as an ESM import specifier. */
575
+ function normalizeImportPath(path) {
576
+ const normalizedPath = path.split(sep).join("/");
577
+ return normalizedPath.startsWith(".") ? normalizedPath : `./${normalizedPath}`;
578
+ }
579
+ /** Normalize a generated file path for package.json imports. */
580
+ function normalizePackageJsonPath(path) {
581
+ return normalizeImportPath(path).replace(LEADING_DOT_SLASH_PATTERN, "./");
582
+ }
583
+ /** Add or update the package import alias used by dynamic generated actions. */
584
+ async function updateAppConfigImportAlias(projectRoot, runtimeConfigPath) {
585
+ const pkg = await NpmPackageJson.load(projectRoot);
586
+ const existingImports = typeof pkg.content.imports === "object" && pkg.content.imports !== null ? pkg.content.imports : {};
587
+ pkg.update({ imports: {
588
+ ...existingImports,
589
+ [APP_CONFIG_IMPORT_ALIAS]: normalizePackageJsonPath(runtimeConfigPath)
590
+ } });
591
+ await pkg.save();
592
+ }
593
+ /** Remove the package import alias used only by dynamic generated actions. */
594
+ async function deleteAppConfigImportAlias(projectRoot) {
595
+ const pkg = await NpmPackageJson.load(projectRoot);
596
+ const existingImports = typeof pkg.content.imports === "object" && pkg.content.imports !== null ? pkg.content.imports : {};
597
+ if (!("#app.commerce.config" in existingImports)) return;
598
+ const imports = { ...existingImports };
599
+ delete imports[APP_CONFIG_IMPORT_ALIAS];
600
+ if (Object.keys(imports).length > 0) pkg.update({ imports });
601
+ else pkg.content.imports = void 0;
602
+ await pkg.save();
603
+ }
604
+ /** Write an ESM passthrough module for JavaScript app config files. */
605
+ async function writeJavaScriptAppConfigModule(configFilePath, outputPath) {
606
+ await writeFile(outputPath, [
607
+ "// This file has been auto-generated by `@adobe/aio-commerce-lib-app`",
608
+ "// Do not modify this file directly",
609
+ "",
610
+ `import appConfig from "${normalizeImportPath(relative(dirname(outputPath), configFilePath))}";`,
611
+ "",
612
+ "export default appConfig;",
613
+ ""
614
+ ].join("\n"), "utf-8");
615
+ }
616
+ /** Bundle a TypeScript app config file into runtime-safe ESM. */
617
+ async function bundleTypeScriptAppConfigModule(configFilePath, outputPath) {
618
+ await build({
619
+ entryPoints: [configFilePath],
620
+ outfile: outputPath,
621
+ bundle: true,
622
+ format: "esm",
623
+ platform: "node",
624
+ target: "node22",
625
+ packages: "external",
626
+ logLevel: "silent"
627
+ });
628
+ }
629
+ /** Generate the runtime-safe app config module used by generated runtime actions. */
630
+ async function generateRuntimeAppConfigModule() {
631
+ const projectRoot = await getProjectRootDirectory();
632
+ const runtimeConfigPath = getRuntimeAppConfigPath();
633
+ await makeOutputDirFor(dirname(runtimeConfigPath));
634
+ const outputPath = join(projectRoot, runtimeConfigPath);
635
+ const configFilePath = await resolveCommerceAppConfig(projectRoot);
636
+ if (!configFilePath) throw new Error("Dynamic list options require an app.commerce.config.* file so generated actions can import the option factories at runtime.");
637
+ consola$1.info("Generating JS config module...");
638
+ if (TYPESCRIPT_CONFIG_EXTENSIONS.has(extname(configFilePath))) await bundleTypeScriptAppConfigModule(configFilePath, outputPath);
639
+ else await writeJavaScriptAppConfigModule(configFilePath, outputPath);
640
+ await updateAppConfigImportAlias(projectRoot, runtimeConfigPath);
641
+ consola$1.success(`Generated JS config module: ${relative(process.cwd(), outputPath)}`);
642
+ }
643
+ /** Remove the generated app config module when generated actions use static JSON. */
644
+ async function cleanupRuntimeAppConfigModule() {
645
+ const projectRoot = await getProjectRootDirectory();
646
+ await rm(join(projectRoot, getRuntimeAppConfigPath()), { force: true });
647
+ await deleteAppConfigImportAlias(projectRoot);
648
+ }
649
+ /**
650
+ * Prepare runtime-side config artifacts consumed by generated actions: the
651
+ * bundled ESM module and its `#app.commerce.config` package import alias.
652
+ *
653
+ * Generates them for dynamic schemas, cleans them up for static ones.
654
+ */
655
+ async function prepareRuntimeAppConfigModule(appManifest) {
656
+ if (hasDynamicAppConfig(appManifest)) {
657
+ await generateRuntimeAppConfigModule();
658
+ return;
659
+ }
660
+ await cleanupRuntimeAppConfigModule();
661
+ }
662
+ /** Switch static JSON imports to the generated runtime config module for dynamic schemas. */
663
+ function applyRuntimeAppConfigImport(template, actionName) {
664
+ if (actionName === "app-config" || actionName === "installation") return template.replace(STATIC_APP_MANIFEST_IMPORT, DYNAMIC_APP_CONFIG_IMPORT);
665
+ if (actionName === "config") return template.replace(STATIC_CONFIG_SCHEMA_IMPORT, DYNAMIC_APP_CONFIG_IMPORT).replace("const args = { configSchema };", "const args = { configSchema: appConfig.businessConfig.schema };");
666
+ return template;
667
+ }
502
668
  /**
503
669
  * Read an extension point's ext.config.yaml file and return it as a JS object.
504
670
  * @param extensionPointId - The extension point ID to read the config for.
@@ -545,8 +711,10 @@ async function generateActionFiles(appManifest, actions, extensionPointId, templ
545
711
  await makeOutputDirFor(getActionsDir(extensionPointId));
546
712
  const projectRoot = await getProjectRootDirectory();
547
713
  const outputFiles = [];
714
+ const useDynamicImports = hasDynamicAppConfig(appManifest);
548
715
  for (const action of actions) {
549
716
  let template = await readFile(join(templatesDir, action.templateFile), "utf-8");
717
+ if (useDynamicImports) template = applyRuntimeAppConfigImport(template, action.name);
550
718
  if (action.name === "installation") {
551
719
  const scriptsTemplate = await generateCustomScriptsTemplate(await readFile(join(templatesDir, "app-management", "custom-scripts.js.template"), "utf-8"), appManifest);
552
720
  template = applyCustomScripts(template, scriptsTemplate);
@@ -614,6 +782,7 @@ async function generateRegistrationActionFile(appManifest, extensionPointId, tem
614
782
  * @param templatesDir - The directory to load templates from, for testing purposes. Defaults to the generated actions template root.
615
783
  */
616
784
  async function run$5(appManifest, templatesDir = TEMPLATES_DIR) {
785
+ await prepareRuntimeAppConfigModule(appManifest);
617
786
  await generateActionFiles(appManifest, getRuntimeActions(await updateExtConfig(appManifest, EXTENSIBILITY_EXTENSION_POINT_ID), "app-management"), EXTENSIBILITY_EXTENSION_POINT_ID, templatesDir);
618
787
  if (hasBusinessConfigSchema(appManifest)) await generateActionFiles(appManifest, getRuntimeActions(await updateExtConfig(appManifest, CONFIGURATION_EXTENSION_POINT_ID), "business-configuration"), CONFIGURATION_EXTENSION_POINT_ID, templatesDir);
619
788
  if (hasAdminUiSdk(appManifest)) {
@@ -635,10 +804,18 @@ async function exec$5() {
635
804
  //#endregion
636
805
  //#region source/commands/generate/manifest/main.ts
637
806
  async function run$4(appConfig) {
807
+ if (hasDynamicAppConfig(appConfig)) {
808
+ const stalePath = join(await getProjectRootDirectory(), getManifestPath());
809
+ if (await access(stalePath).then(() => true, () => false)) {
810
+ await rm(stalePath, { force: true });
811
+ consola$1.success(`Removed stale ${APP_MANIFEST_FILE}`);
812
+ }
813
+ return;
814
+ }
638
815
  consola$1.info("Generating app manifest...");
639
816
  const contents = stringify$1(appConfig, null, 2);
640
817
  await writeFile(join(await makeOutputDirFor(getGeneratedDir(EXTENSIBILITY_EXTENSION_POINT_ID)), APP_MANIFEST_FILE), contents, "utf-8");
641
- consola$1.success(`Generated ${APP_MANIFEST_FILE}`);
818
+ consola$1.success(`Generated ${APP_MANIFEST_FILE}\n`);
642
819
  }
643
820
  /** Run the generate manifest command */
644
821
  async function exec$4() {
@@ -670,7 +847,6 @@ async function run$3(appConfig) {
670
847
  consola$1.debug("Business configuration schema not found in application configuration. Nothing to do.");
671
848
  return;
672
849
  }
673
- consola$1.info("Generating configuration schema...");
674
850
  const projectDir = await getProjectRootDirectory();
675
851
  const envPath = join(projectDir, ".env");
676
852
  await touch(envPath);
@@ -680,9 +856,19 @@ async function run$3(appConfig) {
680
856
  if ("AIO_COMMERCE_CONFIG_ENCRYPTION_KEY" in process.env && String(process.env.AIO_COMMERCE_CONFIG_ENCRYPTION_KEY).trim().length > 0) execSync(`${packageExec} aio-commerce-lib-config encryption validate`);
681
857
  else execSync(`${packageExec} aio-commerce-lib-config encryption setup`);
682
858
  }
859
+ if (hasDynamicAppConfig(appConfig)) {
860
+ const stalePath = join(projectDir, getSchemaPath());
861
+ if (await access(stalePath).then(() => true, () => false)) {
862
+ await rm(stalePath, { force: true });
863
+ consola$1.success(`Removed stale ${CONFIG_SCHEMA_FILE_NAME}`);
864
+ }
865
+ return;
866
+ }
867
+ consola$1.info("Generating configuration schema...");
868
+ const outputDir = await makeOutputDirFor(getGeneratedDir(CONFIGURATION_EXTENSION_POINT_ID));
683
869
  const contents = stringify$1(appConfig.businessConfig.schema, null, 2);
684
- await writeFile(join(await makeOutputDirFor(getGeneratedDir(CONFIGURATION_EXTENSION_POINT_ID)), CONFIG_SCHEMA_FILE_NAME), contents, "utf-8");
685
- consola$1.success(`Generated ${CONFIG_SCHEMA_FILE_NAME}`);
870
+ await writeFile(join(outputDir, CONFIG_SCHEMA_FILE_NAME), contents, "utf-8");
871
+ consola$1.success(`Generated ${CONFIG_SCHEMA_FILE_NAME}\n`);
686
872
  }
687
873
  /** Run the generate schema command */
688
874
  async function exec$3() {
@@ -797,6 +983,7 @@ async function syncImsCredentials() {
797
983
  */
798
984
  async function run$1(extension, templatesDir = TEMPLATES_DIR) {
799
985
  const appManifest = await loadAppManifest();
986
+ await prepareRuntimeAppConfigModule(appManifest);
800
987
  if (extension === "extensibility/1") {
801
988
  const { doc: extensibilityExtConfig } = await readExtConfig(EXTENSIBILITY_EXTENSION_POINT_ID);
802
989
  await run$4(appManifest);
@@ -1206,7 +1393,7 @@ function runInstall(packageManager, dependencies, cwd = process.cwd()) {
1206
1393
  */
1207
1394
  function installDependencies(packageManager, domains, cwd = process.cwd()) {
1208
1395
  const packages = [];
1209
- if (domains.has("businessConfig.schema")) packages.push(`@adobe/aio-commerce-lib-config@^1.4.0`);
1396
+ if (domains.has("businessConfig.schema")) packages.push(`@adobe/aio-commerce-lib-config@^1.5.1`);
1210
1397
  if (packages.length === 0) {
1211
1398
  consola$1.info("No additional domain dependencies to install.");
1212
1399
  return;
@@ -1233,7 +1420,7 @@ async function ensureInstallYaml(domains, cwd = process.cwd()) {
1233
1420
 
1234
1421
  //#endregion
1235
1422
  //#region source/commands/init/main.ts
1236
- const REQUIRED_DEPENDENCIES = ["@adobe/aio-commerce-sdk", `@adobe/aio-commerce-lib-app@1.5.0`];
1423
+ const REQUIRED_DEPENDENCIES = ["@adobe/aio-commerce-sdk", `@adobe/aio-commerce-lib-app@1.7.0`];
1237
1424
  /** Initialize the project */
1238
1425
  async function run(flags, extraOptions) {
1239
1426
  consola$1.start("Initializing app...");
@@ -1298,9 +1485,7 @@ Examples:
1298
1485
  /** Run all generate targets in sequence */
1299
1486
  async function generateAll() {
1300
1487
  await exec$5();
1301
- consola.log.raw("");
1302
1488
  await exec$4();
1303
- consola.log.raw("");
1304
1489
  await exec$3();
1305
1490
  }
1306
1491
  /** Command handlers registry mapping command names to their subcommand handlers */
@@ -16,7 +16,7 @@
16
16
  import { appConfigRuntimeAction } from "@adobe/aio-commerce-lib-app/actions/app-config";
17
17
 
18
18
  // The manifest is always at this relative constant path from the action.
19
- import commerceAppManifest from "../../app.commerce.manifest.json" with { type: "json" };
19
+ import appConfig from "../../app.commerce.manifest.json" with { type: "json" };
20
20
 
21
- const args = { appConfig: commerceAppManifest };
21
+ const args = { appConfig };
22
22
  export const main = appConfigRuntimeAction(args);