@adobe/aio-commerce-lib-app 1.4.0 → 1.6.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 (59) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/dist/cjs/actions/app-config.cjs +17 -4
  3. package/dist/cjs/actions/app-config.d.cts +3 -4
  4. package/dist/cjs/actions/config.cjs +21 -16
  5. package/dist/cjs/actions/config.d.cts +1 -2
  6. package/dist/cjs/actions/installation.cjs +20 -14
  7. package/dist/cjs/actions/installation.d.cts +4 -5
  8. package/dist/cjs/actions/registration.cjs +1 -2
  9. package/dist/cjs/actions/registration.d.cts +2 -3
  10. package/dist/cjs/actions/scope-tree.cjs +5 -5
  11. package/dist/cjs/actions/scope-tree.d.cts +1 -4
  12. package/dist/cjs/{admin-ui-sdk-BiSopnKI.d.cts → admin-ui-sdk-DZZJCrdT.d.cts} +1 -1
  13. package/dist/cjs/{app-C6kImBl7.d.cts → app-CakwxQvs.d.cts} +129 -20
  14. package/dist/cjs/commands/index.cjs +236 -45
  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 +354 -391
  18. package/dist/cjs/{config-ct-qMOGj.cjs → config-FNMclIFO.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-Dw2NvVOY.d.cts} +2 -2
  21. package/dist/cjs/{logging-BTevALnL.cjs → logging-BVz3weoC.cjs} +1 -1
  22. package/dist/cjs/management/index.cjs +1 -1
  23. package/dist/cjs/management/index.d.cts +3 -3
  24. package/dist/cjs/{management-D1QXg4YU.cjs → management-Cvsz4VMf.cjs} +34 -9
  25. package/dist/cjs/{router-CFErodHU.cjs → router-BOR7T6qR.cjs} +1 -1
  26. package/dist/cjs/{schemas-CukVpc19.cjs → schemas-FngDuIeo.cjs} +1 -1
  27. package/dist/{es/step-0eI2x4C9.d.mts → cjs/step-CKVE0aJi.d.cts} +3 -3
  28. package/dist/cjs/{validate-b_bI4mDb.cjs → validate-DydOAZha.cjs} +4 -4
  29. package/dist/cjs/{webhooks-DS1BtgED.cjs → webhooks-tbZy9G3p.cjs} +4 -4
  30. package/dist/es/actions/app-config.d.mts +3 -4
  31. package/dist/es/actions/app-config.mjs +18 -4
  32. package/dist/es/actions/config.d.mts +1 -2
  33. package/dist/es/actions/config.mjs +20 -15
  34. package/dist/es/actions/installation.d.mts +4 -5
  35. package/dist/es/actions/installation.mjs +19 -13
  36. package/dist/es/actions/registration.d.mts +2 -3
  37. package/dist/es/actions/registration.mjs +1 -1
  38. package/dist/es/actions/scope-tree.d.mts +1 -4
  39. package/dist/es/actions/scope-tree.mjs +4 -4
  40. package/dist/es/{admin-ui-sdk-CCo2SWiL.d.mts → admin-ui-sdk-hu6iWr0A.d.mts} +1 -1
  41. package/dist/es/{app-DcY6dJiQ.d.mts → app-CakwxQvs.d.mts} +129 -20
  42. package/dist/es/commands/index.mjs +218 -27
  43. package/dist/es/commands/templates/app-management/app-config.js.template +2 -2
  44. package/dist/es/config/index.d.mts +354 -391
  45. package/dist/es/config/index.mjs +3 -3
  46. package/dist/es/{config-DGPFTk6w.mjs → config-CcE0EBG7.mjs} +4 -5
  47. package/dist/es/{index-CCov0odd.d.mts → index-Bo0tQsVq.d.mts} +2 -2
  48. package/dist/es/management/index.d.mts +3 -3
  49. package/dist/es/management/index.mjs +1 -1
  50. package/dist/es/{management-CCsOfniv.mjs → management-BZ4Y6lVp.mjs} +33 -8
  51. package/dist/{cjs/step-CWYnKbga.d.cts → es/step-D64mMPrt.d.mts} +3 -3
  52. package/dist/es/{validate-Dn3lLTGj.mjs → validate-Du3LhCre.mjs} +3 -3
  53. package/dist/es/{webhooks-Dhrkkip7.mjs → webhooks-B5oq9ULL.mjs} +3 -3
  54. package/package.json +16 -11
  55. /package/dist/cjs/{chunk-DS2yp5vX.cjs → chunk-Cozy-1ZF.cjs} +0 -0
  56. /package/dist/es/{error-DHlYzkbb.mjs → error-_RMwtrUA.mjs} +0 -0
  57. /package/dist/es/{logging-XIUXDK5T.mjs → logging-DbJHXSKh.mjs} +0 -0
  58. /package/dist/es/{router-BxaxEEu3.mjs → router-D58JJHHA.mjs} +0 -0
  59. /package/dist/es/{schemas-DOcnD16x.mjs → schemas-hRovglBF.mjs} +0 -0
@@ -13,24 +13,28 @@
13
13
  * governing permissions and limitations under the License.
14
14
  */
15
15
 
16
- const require_chunk = require('../chunk-DS2yp5vX.cjs');
17
- const require_webhooks = require('../webhooks-DS1BtgED.cjs');
18
- const require_validate = require('../validate-b_bI4mDb.cjs');
19
- const require_config = require('../config-ct-qMOGj.cjs');
20
- const require_error = require('../error-C5LNOZ4f.cjs');
21
- const require_logging = require('../logging-BTevALnL.cjs');
16
+ const require_chunk = require('../chunk-Cozy-1ZF.cjs');
17
+ const require_webhooks = require('../webhooks-tbZy9G3p.cjs');
18
+ const require_validate = require('../validate-DydOAZha.cjs');
19
+ const require_logging = require('../logging-BVz3weoC.cjs');
20
+ const require_error = require('../error-D-N0PKSl.cjs');
21
+ const require_config = require('../config-FNMclIFO.cjs');
22
+ let _adobe_aio_commerce_lib_config = require("@adobe/aio-commerce-lib-config");
22
23
  let _adobe_aio_commerce_lib_core_error = require("@adobe/aio-commerce-lib-core/error");
23
- let path = require("path");
24
- path = require_chunk.__toESM(path, 1);
25
- let fs = require("fs");
26
- let fs_promises = require("fs/promises");
27
24
  let consola = require("consola");
28
25
  consola = require_chunk.__toESM(consola, 1);
26
+ let path = require("path");
27
+ path = require_chunk.__toESM(path, 1);
29
28
  let prettier = require("prettier");
30
29
  prettier = require_chunk.__toESM(prettier, 1);
30
+ let fs = require("fs");
31
+ let fs_promises = require("fs/promises");
31
32
  let url = require("url");
32
33
  let yaml = require("yaml");
34
+ let _npmcli_package_json = require("@npmcli/package-json");
35
+ _npmcli_package_json = require_chunk.__toESM(_npmcli_package_json, 1);
33
36
  let consola_utils = require("consola/utils");
37
+ let esbuild = require("esbuild");
34
38
  let safe_stable_stringify = require("safe-stable-stringify");
35
39
  safe_stable_stringify = require_chunk.__toESM(safe_stable_stringify, 1);
36
40
  let child_process = require("child_process");
@@ -40,8 +44,6 @@ let _adobe_aio_lib_ims = require("@adobe/aio-lib-ims");
40
44
  _adobe_aio_lib_ims = require_chunk.__toESM(_adobe_aio_lib_ims, 1);
41
45
  let dotenv = require("dotenv");
42
46
  dotenv = require_chunk.__toESM(dotenv, 1);
43
- let _npmcli_package_json = require("@npmcli/package-json");
44
- _npmcli_package_json = require_chunk.__toESM(_npmcli_package_json, 1);
45
47
 
46
48
  //#region source/commands/constants.ts
47
49
  /** The name of the package containing all the generated runtime actions */
@@ -64,6 +66,10 @@ const ADMIN_UI_SDK_PACKAGE_NAME = "admin-ui-sdk";
64
66
  const ADMIN_UI_SDK_ACTIONS_PATH = `${GENERATED_PATH}/actions/registration`;
65
67
  /** The name of the configuration schema file */
66
68
  const APP_MANIFEST_FILE = "app.commerce.manifest.json";
69
+ /** The name of the generated runtime-safe app config module (dynamic schemas only). */
70
+ const RUNTIME_APP_CONFIG_FILE = "app.commerce.config.js";
71
+ /** Package import alias for the generated runtime-safe app config module. */
72
+ const APP_CONFIG_IMPORT_ALIAS = "#app.commerce.config";
67
73
  /** The name of the commerce app configuration file */
68
74
  const COMMERCE_APP_CONFIG_FILE = "app.commerce.config";
69
75
  /** The name of the configuration schema file */
@@ -103,6 +109,14 @@ async function loadAppManifest() {
103
109
  return appConfig;
104
110
  }
105
111
  /**
112
+ * Whether the app config contains anything that can't be JSON-serialized as-is
113
+ * and therefore requires generating a runtime-safe ESM config module.
114
+ */
115
+ function hasDynamicAppConfig(appConfig) {
116
+ const schema = appConfig.businessConfig?.schema;
117
+ return Array.isArray(schema) && (0, _adobe_aio_commerce_lib_config.hasDynamicSchema)(schema);
118
+ }
119
+ /**
106
120
  * Path to an extension point's `.generated` directory, relative to the project root.
107
121
  * @param extensionPointId - The extension point ID, e.g. "commerce/extensibility/1"
108
122
  */
@@ -145,6 +159,21 @@ function getAdminUiSdkActionsDir(extensionPointId) {
145
159
  function getAdminUiSdkRegistrationActionPath(extensionPointId) {
146
160
  return (0, path.join)(getAdminUiSdkActionsDir(extensionPointId), "index.js");
147
161
  }
162
+ /** Path to the generated app manifest JSON file, relative to the project root. */
163
+ function getManifestPath() {
164
+ return (0, path.join)(getGeneratedDir(EXTENSIBILITY_EXTENSION_POINT_ID), APP_MANIFEST_FILE);
165
+ }
166
+ /**
167
+ * Path to the generated runtime-safe app config ESM module, relative to the
168
+ * project root. Used when the business config schema contains dynamic options.
169
+ */
170
+ function getRuntimeAppConfigPath() {
171
+ return (0, path.join)(getGeneratedDir(EXTENSIBILITY_EXTENSION_POINT_ID), RUNTIME_APP_CONFIG_FILE);
172
+ }
173
+ /** Path to the generated configuration schema file, relative to the project root. */
174
+ function getSchemaPath() {
175
+ return (0, path.join)(getGeneratedDir(CONFIGURATION_EXTENSION_POINT_ID), CONFIG_SCHEMA_FILE_NAME);
176
+ }
148
177
 
149
178
  //#endregion
150
179
  //#region source/commands/generate/actions/config.ts
@@ -288,12 +317,12 @@ function buildAdminUiSdkExtConfig() {
288
317
  * Read a YAML file and return a {@link Document}
289
318
  * @param path - The path to the YAML file
290
319
  */
291
- async function readYamlFile(path$3) {
320
+ async function readYamlFile(path$5) {
292
321
  let doc = new yaml.Document();
293
- if ((0, fs.existsSync)(path$3)) try {
294
- doc = (0, yaml.parseDocument)(await (0, fs_promises.readFile)(path$3, "utf-8"), { keepSourceTokens: true });
322
+ if ((0, fs.existsSync)(path$5)) try {
323
+ doc = (0, yaml.parseDocument)(await (0, fs_promises.readFile)(path$5, "utf-8"), { keepSourceTokens: true });
295
324
  } catch {
296
- const file = (0, path.basename)(path$3);
325
+ const file = (0, path.basename)(path$5);
297
326
  throw new Error(`Failed to parse ${file}`);
298
327
  }
299
328
  if (doc.contents === null) doc.contents = new yaml.YAMLMap();
@@ -307,18 +336,18 @@ async function readYamlFile(path$3) {
307
336
  * @param typeConfig - Configuration for the node type
308
337
  * @returns The existing or newly created node
309
338
  */
310
- function getOrCreateNode(doc, path$4, options, typeConfig) {
311
- const node = doc.getIn(path$4);
339
+ function getOrCreateNode(doc, path$6, options, typeConfig) {
340
+ const node = doc.getIn(path$6);
312
341
  if (node) {
313
- if (!typeConfig.typeGuard(node)) throw new Error(`Expected ${typeConfig.typeName} at path "${path$4.join(".")}".`);
342
+ if (!typeConfig.typeGuard(node)) throw new Error(`Expected ${typeConfig.typeName} at path "${path$6.join(".")}".`);
314
343
  return node;
315
344
  }
316
- if (doc.hasIn(path$4)) doc.deleteIn(path$4);
317
- const pair = doc.createPair(path$4.at(-1), typeConfig.createNode());
345
+ if (doc.hasIn(path$6)) doc.deleteIn(path$6);
346
+ const pair = doc.createPair(path$6.at(-1), typeConfig.createNode());
318
347
  options.onBeforeCreate?.(pair);
319
- if (path$4.length === 1) doc.add(pair);
320
- else doc.addIn(path$4.slice(0, -1), pair);
321
- return doc.getIn(path$4);
348
+ if (path$6.length === 1) doc.add(pair);
349
+ else doc.addIn(path$6.slice(0, -1), pair);
350
+ return doc.getIn(path$6);
322
351
  }
323
352
  /**
324
353
  * Get or create a sequence at the given path
@@ -326,8 +355,8 @@ function getOrCreateNode(doc, path$4, options, typeConfig) {
326
355
  * @param path - The path to the sequence
327
356
  * @param options - The options for the sequence
328
357
  */
329
- function getOrCreateSeq(doc, path$5, options) {
330
- return getOrCreateNode(doc, path$5, options ?? {}, {
358
+ function getOrCreateSeq(doc, path$7, options) {
359
+ return getOrCreateNode(doc, path$7, options ?? {}, {
331
360
  typeGuard: yaml.isSeq,
332
361
  createNode: () => new yaml.YAMLSeq(),
333
362
  typeName: "sequence"
@@ -339,13 +368,40 @@ function getOrCreateSeq(doc, path$5, options) {
339
368
  * @param path - The path to the map
340
369
  * @param options - The options for the map
341
370
  */
342
- function getOrCreateMap(doc, path$6, options) {
343
- return getOrCreateNode(doc, path$6, options ?? {}, {
371
+ function getOrCreateMap(doc, path$8, options) {
372
+ return getOrCreateNode(doc, path$8, options ?? {}, {
344
373
  typeGuard: yaml.isMap,
345
374
  createNode: () => new yaml.YAMLMap(),
346
375
  typeName: "map"
347
376
  });
348
377
  }
378
+ /**
379
+ * Read the `inputs` map from an existing YAML action definition into a plain
380
+ * object. Used by codegen to merge developer-added inputs with the ones the
381
+ * generator manages, so regeneration does not strip user-added entries.
382
+ *
383
+ * @param existingAction - The YAML map representing the existing action.
384
+ */
385
+ function getExistingInputs(existingAction) {
386
+ const inputs = existingAction?.get("inputs");
387
+ if (!(0, yaml.isMap)(inputs)) return {};
388
+ return Object.fromEntries(inputs.items.map((item) => {
389
+ if (!(0, yaml.isPair)(item)) return [];
390
+ return [String(item.key), item.value];
391
+ }));
392
+ }
393
+ /**
394
+ * Read a string field from an existing YAML action definition. Used by codegen
395
+ * to preserve developer-set values (e.g. `runtime`) across regeneration
396
+ * instead of overwriting them.
397
+ *
398
+ * @param key - The field to read.
399
+ * @param existingAction - The YAML map representing the existing action.
400
+ */
401
+ function getExistingString(key, existingAction) {
402
+ const value = existingAction?.get(key);
403
+ return typeof value === "string" ? value : void 0;
404
+ }
349
405
 
350
406
  //#endregion
351
407
  //#region ../../packages-private/scripting-utils/source/yaml/codegen.ts
@@ -374,19 +430,30 @@ function buildWeb(extConfig, web) {
374
430
  if (!extConfig.hasIn(["web"])) extConfig.add(extConfig.createPair("web", web));
375
431
  }
376
432
  /**
377
- * Build the definition for a runtime action
378
- * @param name - The name of the action
379
- * @param path - The path where the action is located
380
- * @param action - The action definition
433
+ * Build the definition for a runtime action.
434
+ *
435
+ * Developer-added `inputs` keys (anything not in the generator-managed set) on
436
+ * `existingAction` are preserved so that hand-written entries for example
437
+ * factory credentials for `dynamicList` fields — survive regeneration.
438
+ *
439
+ * A `runtime` already set on `existingAction` is likewise preserved, so a
440
+ * developer can pin a different Node runtime (e.g. `nodejs:24`) in
441
+ * `ext.config.yaml` once without codegen reverting it on the next run.
442
+ *
443
+ * @param action - The action definition to build.
444
+ * @param existingAction - The action's previous YAML definition, if any.
381
445
  */
382
- function buildActionDefinition(action) {
446
+ function buildActionDefinition(action, existingAction) {
383
447
  const actionDef = new yaml.YAMLMap();
384
- const inputs = { LOG_LEVEL: "$LOG_LEVEL" };
448
+ const existingInputs = getExistingInputs(existingAction);
449
+ const existingRuntime = getExistingString("runtime", existingAction);
450
+ const managedInputs = { LOG_LEVEL: "$LOG_LEVEL" };
385
451
  actionDef.set("function", action.function);
386
452
  actionDef.set("web", action.web ?? "yes");
387
- actionDef.set("runtime", action.runtime ?? "nodejs:22");
453
+ actionDef.set("runtime", existingRuntime ?? action.runtime ?? "nodejs:22");
388
454
  actionDef.set("inputs", {
389
- ...inputs,
455
+ ...existingInputs,
456
+ ...managedInputs,
390
457
  ...action.inputs ?? {}
391
458
  });
392
459
  actionDef.set("annotations", { ...action.annotations ?? {
@@ -461,11 +528,13 @@ function buildRuntimeManifest(extConfig, manifest) {
461
528
  ], { onBeforeCreate: (pair) => {
462
529
  pair.key.commentBefore = " This package definition is auto-generated. Do not remove or manually edit.";
463
530
  } });
531
+ const existingActions = packageDef.get("actions");
464
532
  const actions = new yaml.YAMLMap();
465
533
  packageDef.set("license", pkg.license ?? "Apache-2.0");
466
534
  packageDef.set("actions", actions);
467
535
  for (const [actionName, action] of Object.entries(pkg.actions ?? {})) {
468
- const actionDef = buildActionDefinition(action);
536
+ const existingAction = (0, yaml.isMap)(existingActions) ? existingActions.get(actionName) : void 0;
537
+ const actionDef = buildActionDefinition(action, (0, yaml.isMap)(existingAction) ? existingAction : void 0);
469
538
  actions.set(actionName, actionDef);
470
539
  }
471
540
  }
@@ -508,6 +577,109 @@ async function writeExtConfig(configPath, doc) {
508
577
  const __dirname$1 = (0, path.dirname)((0, url.fileURLToPath)(require("url").pathToFileURL(__filename).href));
509
578
  /** The path to the action templates directory, sibling to this file. */
510
579
  const TEMPLATES_DIR = (0, path.join)(__dirname$1, "templates");
580
+ const TYPESCRIPT_CONFIG_EXTENSIONS = new Set([
581
+ ".ts",
582
+ ".mts",
583
+ ".cts"
584
+ ]);
585
+ const LEADING_DOT_SLASH_PATTERN = /^\.\//u;
586
+ const DYNAMIC_APP_CONFIG_IMPORT = `import appConfig from "${APP_CONFIG_IMPORT_ALIAS}";`;
587
+ const STATIC_APP_MANIFEST_IMPORT = "import appConfig from \"../../app.commerce.manifest.json\" with { type: \"json\" };";
588
+ const STATIC_CONFIG_SCHEMA_IMPORT = "import configSchema from \"../../configuration-schema.json\" with { type: \"json\" };";
589
+ /** Normalize a path for use as an ESM import specifier. */
590
+ function normalizeImportPath(path$3) {
591
+ const normalizedPath = path$3.split(path.sep).join("/");
592
+ return normalizedPath.startsWith(".") ? normalizedPath : `./${normalizedPath}`;
593
+ }
594
+ /** Normalize a generated file path for package.json imports. */
595
+ function normalizePackageJsonPath(path$4) {
596
+ return normalizeImportPath(path$4).replace(LEADING_DOT_SLASH_PATTERN, "./");
597
+ }
598
+ /** Add or update the package import alias used by dynamic generated actions. */
599
+ async function updateAppConfigImportAlias(projectRoot, runtimeConfigPath) {
600
+ const pkg = await _npmcli_package_json.default.load(projectRoot);
601
+ const existingImports = typeof pkg.content.imports === "object" && pkg.content.imports !== null ? pkg.content.imports : {};
602
+ pkg.update({ imports: {
603
+ ...existingImports,
604
+ [APP_CONFIG_IMPORT_ALIAS]: normalizePackageJsonPath(runtimeConfigPath)
605
+ } });
606
+ await pkg.save();
607
+ }
608
+ /** Remove the package import alias used only by dynamic generated actions. */
609
+ async function deleteAppConfigImportAlias(projectRoot) {
610
+ const pkg = await _npmcli_package_json.default.load(projectRoot);
611
+ const existingImports = typeof pkg.content.imports === "object" && pkg.content.imports !== null ? pkg.content.imports : {};
612
+ if (!("#app.commerce.config" in existingImports)) return;
613
+ const imports = { ...existingImports };
614
+ delete imports[APP_CONFIG_IMPORT_ALIAS];
615
+ if (Object.keys(imports).length > 0) pkg.update({ imports });
616
+ else pkg.content.imports = void 0;
617
+ await pkg.save();
618
+ }
619
+ /** Write an ESM passthrough module for JavaScript app config files. */
620
+ async function writeJavaScriptAppConfigModule(configFilePath, outputPath) {
621
+ await (0, fs_promises.writeFile)(outputPath, [
622
+ "// This file has been auto-generated by `@adobe/aio-commerce-lib-app`",
623
+ "// Do not modify this file directly",
624
+ "",
625
+ `import appConfig from "${normalizeImportPath((0, path.relative)((0, path.dirname)(outputPath), configFilePath))}";`,
626
+ "",
627
+ "export default appConfig;",
628
+ ""
629
+ ].join("\n"), "utf-8");
630
+ }
631
+ /** Bundle a TypeScript app config file into runtime-safe ESM. */
632
+ async function bundleTypeScriptAppConfigModule(configFilePath, outputPath) {
633
+ await (0, esbuild.build)({
634
+ entryPoints: [configFilePath],
635
+ outfile: outputPath,
636
+ bundle: true,
637
+ format: "esm",
638
+ platform: "node",
639
+ target: "node22",
640
+ packages: "external",
641
+ logLevel: "silent"
642
+ });
643
+ }
644
+ /** Generate the runtime-safe app config module used by generated runtime actions. */
645
+ async function generateRuntimeAppConfigModule() {
646
+ const projectRoot = await require_config.getProjectRootDirectory();
647
+ const runtimeConfigPath = getRuntimeAppConfigPath();
648
+ await require_config.makeOutputDirFor((0, path.dirname)(runtimeConfigPath));
649
+ const outputPath = (0, path.join)(projectRoot, runtimeConfigPath);
650
+ const configFilePath = await require_config.resolveCommerceAppConfig(projectRoot);
651
+ if (!configFilePath) throw new Error("Dynamic list options require an app.commerce.config.* file so generated actions can import the option factories at runtime.");
652
+ consola.consola.info("Generating JS config module...");
653
+ if (TYPESCRIPT_CONFIG_EXTENSIONS.has((0, path.extname)(configFilePath))) await bundleTypeScriptAppConfigModule(configFilePath, outputPath);
654
+ else await writeJavaScriptAppConfigModule(configFilePath, outputPath);
655
+ await updateAppConfigImportAlias(projectRoot, runtimeConfigPath);
656
+ consola.consola.success(`Generated JS config module: ${(0, path.relative)(process.cwd(), outputPath)}`);
657
+ }
658
+ /** Remove the generated app config module when generated actions use static JSON. */
659
+ async function cleanupRuntimeAppConfigModule() {
660
+ const projectRoot = await require_config.getProjectRootDirectory();
661
+ await (0, fs_promises.rm)((0, path.join)(projectRoot, getRuntimeAppConfigPath()), { force: true });
662
+ await deleteAppConfigImportAlias(projectRoot);
663
+ }
664
+ /**
665
+ * Prepare runtime-side config artifacts consumed by generated actions: the
666
+ * bundled ESM module and its `#app.commerce.config` package import alias.
667
+ *
668
+ * Generates them for dynamic schemas, cleans them up for static ones.
669
+ */
670
+ async function prepareRuntimeAppConfigModule(appManifest) {
671
+ if (hasDynamicAppConfig(appManifest)) {
672
+ await generateRuntimeAppConfigModule();
673
+ return;
674
+ }
675
+ await cleanupRuntimeAppConfigModule();
676
+ }
677
+ /** Switch static JSON imports to the generated runtime config module for dynamic schemas. */
678
+ function applyRuntimeAppConfigImport(template, actionName) {
679
+ if (actionName === "app-config" || actionName === "installation") return template.replace(STATIC_APP_MANIFEST_IMPORT, DYNAMIC_APP_CONFIG_IMPORT);
680
+ if (actionName === "config") return template.replace(STATIC_CONFIG_SCHEMA_IMPORT, DYNAMIC_APP_CONFIG_IMPORT).replace("const args = { configSchema };", "const args = { configSchema: appConfig.businessConfig.schema };");
681
+ return template;
682
+ }
511
683
  /**
512
684
  * Read an extension point's ext.config.yaml file and return it as a JS object.
513
685
  * @param extensionPointId - The extension point ID to read the config for.
@@ -554,8 +726,10 @@ async function generateActionFiles(appManifest, actions, extensionPointId, templ
554
726
  await require_config.makeOutputDirFor(getActionsDir(extensionPointId));
555
727
  const projectRoot = await require_config.getProjectRootDirectory();
556
728
  const outputFiles = [];
729
+ const useDynamicImports = hasDynamicAppConfig(appManifest);
557
730
  for (const action of actions) {
558
731
  let template = await (0, fs_promises.readFile)((0, path.join)(templatesDir, action.templateFile), "utf-8");
732
+ if (useDynamicImports) template = applyRuntimeAppConfigImport(template, action.name);
559
733
  if (action.name === "installation") {
560
734
  const scriptsTemplate = await generateCustomScriptsTemplate(await (0, fs_promises.readFile)((0, path.join)(templatesDir, "app-management", "custom-scripts.js.template"), "utf-8"), appManifest);
561
735
  template = applyCustomScripts(template, scriptsTemplate);
@@ -623,6 +797,7 @@ async function generateRegistrationActionFile(appManifest, extensionPointId, tem
623
797
  * @param templatesDir - The directory to load templates from, for testing purposes. Defaults to the generated actions template root.
624
798
  */
625
799
  async function run$5(appManifest, templatesDir = TEMPLATES_DIR) {
800
+ await prepareRuntimeAppConfigModule(appManifest);
626
801
  await generateActionFiles(appManifest, getRuntimeActions(await updateExtConfig(appManifest, EXTENSIBILITY_EXTENSION_POINT_ID), "app-management"), EXTENSIBILITY_EXTENSION_POINT_ID, templatesDir);
627
802
  if (require_validate.hasBusinessConfigSchema(appManifest)) await generateActionFiles(appManifest, getRuntimeActions(await updateExtConfig(appManifest, CONFIGURATION_EXTENSION_POINT_ID), "business-configuration"), CONFIGURATION_EXTENSION_POINT_ID, templatesDir);
628
803
  if (require_webhooks.hasAdminUiSdk(appManifest)) {
@@ -644,10 +819,18 @@ async function exec$5() {
644
819
  //#endregion
645
820
  //#region source/commands/generate/manifest/main.ts
646
821
  async function run$4(appConfig) {
822
+ if (hasDynamicAppConfig(appConfig)) {
823
+ const stalePath = (0, path.join)(await require_config.getProjectRootDirectory(), getManifestPath());
824
+ if (await (0, fs_promises.access)(stalePath).then(() => true, () => false)) {
825
+ await (0, fs_promises.rm)(stalePath, { force: true });
826
+ consola.consola.success(`Removed stale ${APP_MANIFEST_FILE}`);
827
+ }
828
+ return;
829
+ }
647
830
  consola.consola.info("Generating app manifest...");
648
831
  const contents = (0, safe_stable_stringify.stringify)(appConfig, null, 2);
649
832
  await (0, fs_promises.writeFile)((0, path.join)(await require_config.makeOutputDirFor(getGeneratedDir(EXTENSIBILITY_EXTENSION_POINT_ID)), APP_MANIFEST_FILE), contents, "utf-8");
650
- consola.consola.success(`Generated ${APP_MANIFEST_FILE}`);
833
+ consola.consola.success(`Generated ${APP_MANIFEST_FILE}\n`);
651
834
  }
652
835
  /** Run the generate manifest command */
653
836
  async function exec$4() {
@@ -679,7 +862,6 @@ async function run$3(appConfig) {
679
862
  consola.consola.debug("Business configuration schema not found in application configuration. Nothing to do.");
680
863
  return;
681
864
  }
682
- consola.consola.info("Generating configuration schema...");
683
865
  const projectDir = await require_config.getProjectRootDirectory();
684
866
  const envPath = (0, path.join)(projectDir, ".env");
685
867
  await touch(envPath);
@@ -689,9 +871,19 @@ async function run$3(appConfig) {
689
871
  if ("AIO_COMMERCE_CONFIG_ENCRYPTION_KEY" in process.env && String(process.env.AIO_COMMERCE_CONFIG_ENCRYPTION_KEY).trim().length > 0) (0, child_process.execSync)(`${packageExec} aio-commerce-lib-config encryption validate`);
690
872
  else (0, child_process.execSync)(`${packageExec} aio-commerce-lib-config encryption setup`);
691
873
  }
874
+ if (hasDynamicAppConfig(appConfig)) {
875
+ const stalePath = (0, path.join)(projectDir, getSchemaPath());
876
+ if (await (0, fs_promises.access)(stalePath).then(() => true, () => false)) {
877
+ await (0, fs_promises.rm)(stalePath, { force: true });
878
+ consola.consola.success(`Removed stale ${CONFIG_SCHEMA_FILE_NAME}`);
879
+ }
880
+ return;
881
+ }
882
+ consola.consola.info("Generating configuration schema...");
883
+ const outputDir = await require_config.makeOutputDirFor(getGeneratedDir(CONFIGURATION_EXTENSION_POINT_ID));
692
884
  const contents = (0, safe_stable_stringify.stringify)(appConfig.businessConfig.schema, null, 2);
693
- await (0, fs_promises.writeFile)((0, path.join)(await require_config.makeOutputDirFor(getGeneratedDir(CONFIGURATION_EXTENSION_POINT_ID)), CONFIG_SCHEMA_FILE_NAME), contents, "utf-8");
694
- consola.consola.success(`Generated ${CONFIG_SCHEMA_FILE_NAME}`);
885
+ await (0, fs_promises.writeFile)((0, path.join)(outputDir, CONFIG_SCHEMA_FILE_NAME), contents, "utf-8");
886
+ consola.consola.success(`Generated ${CONFIG_SCHEMA_FILE_NAME}\n`);
695
887
  }
696
888
  /** Run the generate schema command */
697
889
  async function exec$3() {
@@ -806,6 +998,7 @@ async function syncImsCredentials() {
806
998
  */
807
999
  async function run$1(extension, templatesDir = TEMPLATES_DIR) {
808
1000
  const appManifest = await loadAppManifest();
1001
+ await prepareRuntimeAppConfigModule(appManifest);
809
1002
  if (extension === "extensibility/1") {
810
1003
  const { doc: extensibilityExtConfig } = await readExtConfig(EXTENSIBILITY_EXTENSION_POINT_ID);
811
1004
  await run$4(appManifest);
@@ -1215,7 +1408,7 @@ function runInstall(packageManager, dependencies, cwd = process.cwd()) {
1215
1408
  */
1216
1409
  function installDependencies(packageManager, domains, cwd = process.cwd()) {
1217
1410
  const packages = [];
1218
- if (domains.has("businessConfig.schema")) packages.push(`@adobe/aio-commerce-lib-config@^1.3.0`);
1411
+ if (domains.has("businessConfig.schema")) packages.push(`@adobe/aio-commerce-lib-config@^1.5.0`);
1219
1412
  if (packages.length === 0) {
1220
1413
  consola.consola.info("No additional domain dependencies to install.");
1221
1414
  return;
@@ -1242,7 +1435,7 @@ async function ensureInstallYaml(domains, cwd = process.cwd()) {
1242
1435
 
1243
1436
  //#endregion
1244
1437
  //#region source/commands/init/main.ts
1245
- const REQUIRED_DEPENDENCIES = ["@adobe/aio-commerce-sdk", `@adobe/aio-commerce-lib-app@1.4.0`];
1438
+ const REQUIRED_DEPENDENCIES = ["@adobe/aio-commerce-sdk", `@adobe/aio-commerce-lib-app@1.6.0`];
1246
1439
  /** Initialize the project */
1247
1440
  async function run(flags, extraOptions) {
1248
1441
  consola.consola.start("Initializing app...");
@@ -1307,9 +1500,7 @@ Examples:
1307
1500
  /** Run all generate targets in sequence */
1308
1501
  async function generateAll() {
1309
1502
  await exec$5();
1310
- consola.default.log.raw("");
1311
1503
  await exec$4();
1312
- consola.default.log.raw("");
1313
1504
  await exec$3();
1314
1505
  }
1315
1506
  /** 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);
@@ -13,9 +13,9 @@
13
13
  */
14
14
 
15
15
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
16
- const require_webhooks = require('../webhooks-DS1BtgED.cjs');
17
- const require_validate = require('../validate-b_bI4mDb.cjs');
18
- const require_config = require('../config-ct-qMOGj.cjs');
16
+ const require_webhooks = require('../webhooks-tbZy9G3p.cjs');
17
+ const require_validate = require('../validate-DydOAZha.cjs');
18
+ const require_config = require('../config-FNMclIFO.cjs');
19
19
 
20
20
  exports.CommerceAppConfigSchemas = require_validate.CommerceAppConfigSchemas;
21
21
  exports.defineConfig = require_config.defineConfig;