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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +1 -4
  3. package/bin/cli.mjs +24 -0
  4. package/dist/cjs/actions/app-config.cjs +27 -0
  5. package/dist/cjs/actions/app-config.d.cts +15 -0
  6. package/dist/cjs/actions/config.cjs +79 -0
  7. package/dist/cjs/actions/config.d.cts +15 -0
  8. package/dist/cjs/actions/installation.cjs +424 -0
  9. package/dist/cjs/actions/{index.d.cts → installation.d.cts} +4 -3
  10. package/dist/cjs/actions/scope-tree.cjs +97 -0
  11. package/dist/cjs/actions/scope-tree.d.cts +8 -0
  12. package/dist/{es/app-Cx1-6dn0.d.mts → cjs/app-DWX5-Hsf.d.cts} +14 -14
  13. package/dist/cjs/commands/generate/actions/templates/app-management/app-config.js.template +22 -0
  14. package/dist/cjs/commands/generate/actions/templates/app-management/installation.js.template +1 -1
  15. package/dist/cjs/commands/generate/actions/templates/business-configuration/config.js.template +22 -0
  16. package/dist/cjs/commands/generate/actions/templates/business-configuration/scope-tree.js.template +18 -0
  17. package/dist/cjs/commands/index.cjs +91 -106
  18. package/dist/cjs/config/index.cjs +21 -19
  19. package/dist/cjs/config/index.d.cts +52 -352
  20. package/dist/cjs/error-DJ2UAPH2.cjs +24 -0
  21. package/dist/cjs/installation-CLbceU9F.cjs +243 -0
  22. package/dist/cjs/{logging-DYwr5WQk.cjs → logging-IDRQG0as.cjs} +2 -2
  23. package/dist/cjs/management/index.cjs +9 -8
  24. package/dist/cjs/management/index.d.cts +2 -2
  25. package/dist/cjs/parser-BPpg_9QB.cjs +267 -0
  26. package/dist/cjs/router-DCw7oEQ9.cjs +417 -0
  27. package/dist/{es/index-Bxr3zvCT.d.mts → cjs/runner-DemKouFJ.d.cts} +49 -95
  28. package/dist/cjs/{management-Dm5h0E6l.cjs → runner-NHMvoMO2.cjs} +24 -30
  29. package/dist/cjs/schemas-CZ6c8Id9.cjs +98 -0
  30. package/dist/cjs/validate-Btzn9ilZ.cjs +235 -0
  31. package/dist/es/actions/app-config.d.mts +15 -0
  32. package/dist/es/actions/app-config.mjs +25 -0
  33. package/dist/es/actions/config.d.mts +15 -0
  34. package/dist/es/actions/config.mjs +77 -0
  35. package/dist/es/actions/{index.d.mts → installation.d.mts} +4 -3
  36. package/dist/es/actions/{index.mjs → installation.mjs} +27 -427
  37. package/dist/es/actions/scope-tree.d.mts +8 -0
  38. package/dist/es/actions/scope-tree.mjs +95 -0
  39. package/dist/{cjs/app-Dx0ca6oL.d.cts → es/app-BAiyvNo2.d.mts} +14 -14
  40. package/dist/es/commands/generate/actions/templates/app-management/app-config.js.template +22 -0
  41. package/dist/es/commands/generate/actions/templates/app-management/installation.js.template +1 -1
  42. package/dist/es/commands/generate/actions/templates/business-configuration/config.js.template +22 -0
  43. package/dist/es/commands/generate/actions/templates/business-configuration/scope-tree.js.template +18 -0
  44. package/dist/es/commands/index.mjs +68 -84
  45. package/dist/es/config/index.d.mts +52 -352
  46. package/dist/es/config/index.mjs +3 -2
  47. package/dist/es/error-CMV3IjBz.mjs +18 -0
  48. package/dist/es/{error-P7JgUTds.mjs → installation-BTL9X7iv.mjs} +78 -128
  49. package/dist/es/management/index.d.mts +2 -3
  50. package/dist/es/management/index.mjs +1 -1
  51. package/dist/es/parser-CQZTVG6i.mjs +201 -0
  52. package/dist/es/router-CJ4VWoCt.mjs +404 -0
  53. package/dist/{cjs/index-C5SutkJQ.d.cts → es/runner-BD-lItnK.d.mts} +49 -95
  54. package/dist/es/{management-Y7pwEbNI.mjs → runner-vwAhjD5r.mjs} +17 -24
  55. package/dist/es/schemas-B8yIv0_b.mjs +41 -0
  56. package/dist/es/validate-DKnju9-R.mjs +187 -0
  57. package/package.json +38 -24
  58. package/dist/cjs/actions/index.cjs +0 -824
  59. package/dist/cjs/commands/generate/actions/templates/app-management/get-app-config.js.template +0 -62
  60. package/dist/cjs/commands/generate/actions/templates/business-configuration/get-config-schema.js.template +0 -63
  61. package/dist/cjs/commands/generate/actions/templates/business-configuration/get-configuration.js.template +0 -104
  62. package/dist/cjs/commands/generate/actions/templates/business-configuration/get-scope-tree.js.template +0 -69
  63. package/dist/cjs/commands/generate/actions/templates/business-configuration/set-configuration.js.template +0 -125
  64. package/dist/cjs/commands/generate/actions/templates/business-configuration/set-custom-scope-tree.js.template +0 -83
  65. package/dist/cjs/commands/generate/actions/templates/business-configuration/sync-commerce-scopes.js.template +0 -113
  66. package/dist/cjs/commands/generate/actions/templates/business-configuration/unsync-commerce-scopes.js.template +0 -56
  67. package/dist/cjs/config-JQ_n-5Nk.cjs +0 -565
  68. package/dist/cjs/error-Byj1DVHZ.cjs +0 -344
  69. package/dist/es/commands/generate/actions/templates/app-management/get-app-config.js.template +0 -62
  70. package/dist/es/commands/generate/actions/templates/business-configuration/get-config-schema.js.template +0 -63
  71. package/dist/es/commands/generate/actions/templates/business-configuration/get-configuration.js.template +0 -104
  72. package/dist/es/commands/generate/actions/templates/business-configuration/get-scope-tree.js.template +0 -69
  73. package/dist/es/commands/generate/actions/templates/business-configuration/set-configuration.js.template +0 -125
  74. package/dist/es/commands/generate/actions/templates/business-configuration/set-custom-scope-tree.js.template +0 -83
  75. package/dist/es/commands/generate/actions/templates/business-configuration/sync-commerce-scopes.js.template +0 -113
  76. package/dist/es/commands/generate/actions/templates/business-configuration/unsync-commerce-scopes.js.template +0 -56
  77. package/dist/es/config-BSGerqCG.mjs +0 -457
  78. /package/dist/es/{logging-VgerMhp6.mjs → logging-CzmXDzxI.mjs} +0 -0
@@ -1,4 +1,5 @@
1
- import { a as hasExternalEvents, c as hasCustomInstallationSteps, i as hasEventing, r as hasCommerceEvents, s as hasCustomInstallation } from "../error-P7JgUTds.mjs";
2
- import { a as validateCommerceAppConfigDomain, c as hasConfigDomain, d as hasBusinessConfigSchema, i as validateCommerceAppConfig, l as hasMetadata, n as readCommerceAppConfig, o as CommerceAppConfigSchemas, r as resolveCommerceAppConfig, s as getConfigDomains, t as parseCommerceAppConfig, u as hasBusinessConfig, v as defineConfig } from "../config-BSGerqCG.mjs";
1
+ import { a as hasConfigDomain, c as hasBusinessConfigSchema, i as getConfigDomains, n as validateCommerceAppConfigDomain, o as hasMetadata, r as CommerceAppConfigSchemas, s as hasBusinessConfig, t as validateCommerceAppConfig } from "../validate-DKnju9-R.mjs";
2
+ import { a as hasCommerceEvents, n as hasCustomInstallation, o as hasEventing, r as hasCustomInstallationSteps, s as hasExternalEvents } from "../installation-BTL9X7iv.mjs";
3
+ import { d as defineConfig, n as readCommerceAppConfig, r as resolveCommerceAppConfig, t as parseCommerceAppConfig } from "../parser-CQZTVG6i.mjs";
3
4
 
4
5
  export { CommerceAppConfigSchemas, defineConfig, getConfigDomains, hasBusinessConfig, hasBusinessConfigSchema, hasCommerceEvents, hasConfigDomain, hasCustomInstallation, hasCustomInstallationSteps, hasEventing, hasExternalEvents, hasMetadata, parseCommerceAppConfig, readCommerceAppConfig, resolveCommerceAppConfig, validateCommerceAppConfig, validateCommerceAppConfigDomain };
@@ -0,0 +1,18 @@
1
+ import { CommerceSdkValidationError } from "@adobe/aio-commerce-lib-core/error";
2
+
3
+ //#region ../../packages-private/scripting-utils/source/error.ts
4
+ /**
5
+ * This module exports shared error utilities for the AIO Commerce SDK.
6
+ * @packageDocumentation
7
+ */
8
+ /**
9
+ * Stringify an error to a human-friendly string.
10
+ * @param error - The error to stringify.
11
+ */
12
+ function stringifyError(error) {
13
+ if (error instanceof CommerceSdkValidationError) return error.display();
14
+ return error instanceof Error ? error.message : String(error);
15
+ }
16
+
17
+ //#endregion
18
+ export { stringifyError as t };
@@ -1,122 +1,24 @@
1
+ import { i as stringValueSchema, n as booleanValueSchema, r as nonEmptyStringValueSchema, t as alphaNumericOrHyphenSchema } from "./schemas-B8yIv0_b.mjs";
1
2
  import * as v from "valibot";
2
- import { CommerceSdkValidationError } from "@adobe/aio-commerce-lib-core/error";
3
3
 
4
- //#region ../../packages-private/common-utils/source/valibot/schemas.ts
5
- const ALPHANUMERIC_OR_UNDERSCORE_REGEX = {
6
- any: /^[a-zA-Z0-9_]+$/,
7
- lowercase: /^[a-z0-9_]+$/,
8
- uppercase: /^[A-Z0-9_]+$/
9
- };
10
- const ALPHANUMERIC_OR_HYPHEN_REGEX = {
11
- any: /^[a-zA-Z0-9-]+$/,
12
- lowercase: /^[a-z0-9-]+$/,
13
- uppercase: /^[A-Z0-9-]+$/
14
- };
15
- /**
16
- * A schema for a string value.
17
- * @param name The name of the field this schema refers to.
18
- */
19
- function stringValueSchema(name) {
20
- return v.string(`Expected a string value for '${name}'`);
21
- }
22
- /**
23
- * A schema for a non-empty string value.
24
- * @param name The name of the field this schema refers to.
25
- */
26
- function nonEmptyStringValueSchema(name) {
27
- return v.pipe(stringValueSchema(name), v.nonEmpty(`The value of "${name}" must not be empty`));
28
- }
29
- /**
30
- * A schema for a boolean value.
31
- * @param name The name of the field this schema refers to.
32
- */
33
- function booleanValueSchema(name) {
34
- return v.boolean(`Expected a boolean value for '${name}'`);
35
- }
36
- /**
37
- * A schema for a string that only contains alphanumeric characters and underscores.
38
- * @param name The name of the field this schema refers to.
39
- * @param casing The allowed casing for the string (default: "any").
40
- */
41
- function alphaNumericOrUnderscoreSchema(name, casing = "any") {
42
- const casingLabel = casing === "any" ? "" : ` (${casing} only)`;
43
- return v.pipe(stringValueSchema(name), v.regex(ALPHANUMERIC_OR_UNDERSCORE_REGEX[casing], `Only alphanumeric characters and underscores are allowed in string value of "${name}"${casingLabel}`));
44
- }
45
- /**
46
- * A schema for a string that only contains alphanumeric characters and hyphens.
47
- * @param name The name of the field this schema refers to.
48
- * @param casing The allowed casing for the string (default: "any").
49
- */
50
- function alphaNumericOrHyphenSchema(name, casing = "any") {
51
- const casingLabel = casing === "any" ? "" : ` (${casing} only)`;
52
- return v.pipe(stringValueSchema(name), v.regex(ALPHANUMERIC_OR_HYPHEN_REGEX[casing], `Only alphanumeric characters and hyphens are allowed in string value of "${name}"${casingLabel}`));
53
- }
54
-
55
- //#endregion
56
- //#region source/config/schema/installation.ts
57
- const MAX_DESCRIPTION_LENGTH$1 = 255;
58
- const MAX_NAME_LENGTH = 255;
59
- const MAX_MESSAGE_LENGTH = 1e3;
60
- /**
61
- * Regex for script paths that can be relative or absolute.
62
- * Must end with .js extension
63
- * Examples:
64
- * - "./scripts/setup.js"
65
- * - "./setup.js"
66
- * - "../../scripts/setup.js"
67
- */
68
- const SCRIPT_PATH_REGEX = /^(?:\.{0,2}\/)*[\w-/]*[\w-]+\.js$/;
69
- /**
70
- * Schema for custom installation step configuration
71
- */
72
- const CustomInstallationStepSchema = v.object({
73
- script: v.pipe(nonEmptyStringValueSchema("script path"), v.regex(SCRIPT_PATH_REGEX, "Script path must end with .js (e.g., \"./setup.js\", \"./scripts/setup.js\", or \"../../scripts/setup.js\")")),
74
- name: v.pipe(nonEmptyStringValueSchema("step name"), v.maxLength(MAX_NAME_LENGTH, `The step name must not be longer than ${MAX_NAME_LENGTH} characters`)),
75
- description: v.pipe(nonEmptyStringValueSchema("step description"), v.maxLength(MAX_DESCRIPTION_LENGTH$1, `The step description must not be longer than ${MAX_DESCRIPTION_LENGTH$1} characters`))
76
- });
77
- /**
78
- * Schema for installation messages configuration
79
- */
80
- const MessagesSchema = v.object({
81
- preInstallation: v.optional(v.pipe(nonEmptyStringValueSchema("preInstallation message"), v.maxLength(MAX_MESSAGE_LENGTH, `The preInstallation message must not be longer than ${MAX_MESSAGE_LENGTH} characters`))),
82
- postInstallation: v.optional(v.pipe(nonEmptyStringValueSchema("postInstallation message"), v.maxLength(MAX_MESSAGE_LENGTH, `The postInstallation message must not be longer than ${MAX_MESSAGE_LENGTH} characters`)))
83
- });
84
- /**
85
- * Schema for installation configuration
86
- */
87
- const InstallationSchema = v.object({
88
- messages: v.optional(MessagesSchema),
89
- customInstallationSteps: v.pipe(v.optional(v.array(CustomInstallationStepSchema, "Expected an array of custom installation steps")), v.check((input) => {
90
- const steps = input || [];
91
- return new Set(steps.map((step) => step.name)).size === steps.length;
92
- }, "Duplicate step names detected in custom installation steps. Each step must have a unique name."))
93
- });
94
- /**
95
- * Check if config has custom installation settings.
96
- * @param config - The configuration to check.
97
- */
98
- function hasCustomInstallation(config) {
99
- return config.installation !== void 0;
100
- }
101
- /**
102
- * Check if config has custom installation steps.
103
- * @param config - The configuration to check.
104
- */
105
- function hasCustomInstallationSteps(config) {
106
- return Array.isArray(config?.installation?.customInstallationSteps) && config.installation.customInstallationSteps.length > 0;
107
- }
108
-
109
- //#endregion
110
4
  //#region source/config/schema/eventing.ts
111
- const MAX_DESCRIPTION_LENGTH = 255;
5
+ const MAX_DESCRIPTION_LENGTH$1 = 255;
112
6
  const MAX_LABEL_LENGTH = 100;
113
7
  const MAX_KEY_LENGTH = 50;
8
+ const MAX_EVENT_NAME_LENGTH = 180;
114
9
  /**
115
10
  * Regex for Commerce event names that must start with "plugin." or "observer."
116
- * followed by lowercase letters and underscores only.
117
- * Examples: "plugin.order_placed", "observer.catalog_update"
11
+ * followed by one or more dot-separated lowercase segments containing letters
12
+ * and underscores only.
13
+ * Examples: "observer.order_placed", "plugin.sales.api.order_management.place"
14
+ */
15
+ const COMMERCE_EVENT_NAME_REGEX = /^(?:plugin|observer)\.[a-z_]+(?:\.[a-z_]+)*$/;
16
+ /**
17
+ * Regex for external event names.
18
+ * Allows word characters (letters, digits, underscore), hyphens, underscores, and dots.
19
+ * Examples: "external_event", "webhook.received", "my-event_123"
118
20
  */
119
- const COMMERCE_EVENT_NAME_REGEX = /^(?:plugin|observer)\.[a-z_]+$/;
21
+ const EXTERNAL_EVENT_NAME_REGEX = /^[\w\-_.]+$/;
120
22
  /**
121
23
  * Regex for field names according to XSD fieldName pattern.
122
24
  * Field name can either contain only [a-zA-Z0-9_\-\.\[\]] or be set to *.
@@ -125,10 +27,19 @@ const FIELD_NAME_REGEX = /^([a-zA-Z0-9_\-.[\]]+|\*)$/;
125
27
  /**
126
28
  * Schema for Commerce event names.
127
29
  * Validates that the event name starts with "plugin." or "observer."
128
- * followed by lowercase letters and underscores only.
30
+ * followed by one or more dot-separated lowercase segments containing letters
31
+ * and underscores only.
129
32
  */
130
33
  function commerceEventNameSchema() {
131
- return v.pipe(nonEmptyStringValueSchema("event name"), v.regex(COMMERCE_EVENT_NAME_REGEX, "Event name must start with \"plugin.\" or \"observer.\" followed by lowercase letters and underscores only (e.g., \"plugin.order_placed\")"));
34
+ return v.pipe(nonEmptyStringValueSchema("event name"), v.regex(COMMERCE_EVENT_NAME_REGEX, "Event name must start with \"plugin.\" or \"observer.\" followed by one or more dot-separated lowercase segments containing letters and underscores only (e.g., \"observer.order_placed\", \"plugin.sales.api.order_management.place\")"), v.maxLength(MAX_EVENT_NAME_LENGTH, `The event name must not be longer than ${MAX_EVENT_NAME_LENGTH} characters`));
35
+ }
36
+ /**
37
+ * Schema for external event names.
38
+ * Validates that the event name contains only word characters (letters, digits, underscore),
39
+ * hyphens, underscores, and dots.
40
+ */
41
+ function externalEventNameSchema() {
42
+ return v.pipe(nonEmptyStringValueSchema("event name"), v.regex(EXTERNAL_EVENT_NAME_REGEX, "Event name must contain only letters, digits, underscores, hyphens, and dots (e.g., \"external_event\", \"webhook.received\", \"my-event_123\")"), v.maxLength(MAX_EVENT_NAME_LENGTH, `The event name must not be longer than ${MAX_EVENT_NAME_LENGTH} characters`));
132
43
  }
133
44
  /**
134
45
  * Schema for field names.
@@ -151,14 +62,14 @@ function commerceEventFieldSchema() {
151
62
  /** Schema for event provider configuration */
152
63
  const ProviderSchema = v.object({
153
64
  label: v.pipe(nonEmptyStringValueSchema("provider label"), v.maxLength(MAX_LABEL_LENGTH, `The provider label must not be longer than ${MAX_LABEL_LENGTH} characters`)),
154
- description: v.pipe(nonEmptyStringValueSchema("provider description"), v.maxLength(MAX_DESCRIPTION_LENGTH, `The provider description must not be longer than ${MAX_DESCRIPTION_LENGTH} characters`)),
65
+ description: v.pipe(nonEmptyStringValueSchema("provider description"), v.maxLength(MAX_DESCRIPTION_LENGTH$1, `The provider description must not be longer than ${MAX_DESCRIPTION_LENGTH$1} characters`)),
155
66
  key: v.optional(v.pipe(alphaNumericOrHyphenSchema("provider key"), v.maxLength(MAX_KEY_LENGTH, `The provider key must not be longer than ${MAX_KEY_LENGTH} characters`)))
156
67
  });
157
68
  /** Schema for base shared properties between event types. */
158
69
  const BaseEventSchema = v.object({
159
70
  label: v.pipe(nonEmptyStringValueSchema("event label"), v.maxLength(MAX_LABEL_LENGTH, `The event label must not be longer than ${MAX_LABEL_LENGTH} characters`)),
160
- description: v.pipe(nonEmptyStringValueSchema("event description"), v.maxLength(MAX_DESCRIPTION_LENGTH, `The event description must not be longer than ${MAX_DESCRIPTION_LENGTH} characters`)),
161
- runtimeActions: v.array(v.pipe(nonEmptyStringValueSchema("runtime action"), v.regex(/^[a-z0-9-]+\/[a-z0-9-]+$/, "Runtime action must be in the format \"<package>/<action>\" (e.g., \"my-package/my-action\")")), "Expected an array of runtime actions in the format <package>/<action>")
71
+ description: v.pipe(nonEmptyStringValueSchema("event description"), v.maxLength(MAX_DESCRIPTION_LENGTH$1, `The event description must not be longer than ${MAX_DESCRIPTION_LENGTH$1} characters`)),
72
+ runtimeActions: v.array(v.pipe(nonEmptyStringValueSchema("runtime action"), v.regex(/^[a-z0-9-]+\/[a-z0-9-]+$/i, "Runtime action must be in the format \"<package>/<action>\" (e.g., \"my-package/my-action\")")), "Expected an array of runtime actions in the format <package>/<action>")
162
73
  });
163
74
  /**
164
75
  * Schema for rule operator values.
@@ -186,14 +97,14 @@ const CommerceEventSchema = v.object({
186
97
  fields: v.array(commerceEventFieldSchema(), "Expected an array of event field objects with a 'name' property"),
187
98
  rules: v.optional(v.array(CommerceEventRuleSchema, "Expected an array of event rules with field, operator, and value")),
188
99
  destination: v.optional(nonEmptyStringValueSchema("destination")),
189
- hipaaAuditRequired: v.optional(booleanValueSchema("hipaaAuditRequired")),
190
- prioritary: v.optional(booleanValueSchema("prioritary")),
100
+ hipaa_audit_required: v.optional(booleanValueSchema("hipaa_audit_required")),
101
+ priority: v.optional(booleanValueSchema("priority")),
191
102
  force: v.optional(booleanValueSchema("force"))
192
103
  });
193
104
  /** Schema for external event configuration */
194
105
  const ExternalEventSchema = v.object({
195
106
  ...BaseEventSchema.entries,
196
- name: alphaNumericOrUnderscoreSchema("event name", "lowercase")
107
+ name: externalEventNameSchema()
197
108
  });
198
109
  /** Schema for Commerce event source configuration */
199
110
  const CommerceEventSourceSchema = v.object({
@@ -233,19 +144,58 @@ function hasEventing(config) {
233
144
  }
234
145
 
235
146
  //#endregion
236
- //#region ../../packages-private/scripting-utils/source/error.ts
147
+ //#region source/config/schema/installation.ts
148
+ const MAX_DESCRIPTION_LENGTH = 255;
149
+ const MAX_NAME_LENGTH = 255;
150
+ const MAX_MESSAGE_LENGTH = 1e3;
151
+ /**
152
+ * Regex for script paths that can be relative or absolute.
153
+ * Must end with .js extension
154
+ * Examples:
155
+ * - "./scripts/setup.js"
156
+ * - "./setup.js"
157
+ * - "../../scripts/setup.js"
158
+ */
159
+ const SCRIPT_PATH_REGEX = /^(?:\.{0,2}\/)*[\w-/]*[\w-]+\.js$/;
160
+ /**
161
+ * Schema for custom installation step configuration
162
+ */
163
+ const CustomInstallationStepSchema = v.object({
164
+ script: v.pipe(nonEmptyStringValueSchema("script path"), v.regex(SCRIPT_PATH_REGEX, "Script path must end with .js (e.g., \"./setup.js\", \"./scripts/setup.js\", or \"../../scripts/setup.js\")")),
165
+ name: v.pipe(nonEmptyStringValueSchema("step name"), v.maxLength(MAX_NAME_LENGTH, `The step name must not be longer than ${MAX_NAME_LENGTH} characters`)),
166
+ description: v.pipe(nonEmptyStringValueSchema("step description"), v.maxLength(MAX_DESCRIPTION_LENGTH, `The step description must not be longer than ${MAX_DESCRIPTION_LENGTH} characters`))
167
+ });
168
+ /**
169
+ * Schema for installation messages configuration
170
+ */
171
+ const MessagesSchema = v.object({
172
+ preInstallation: v.optional(v.pipe(nonEmptyStringValueSchema("preInstallation message"), v.maxLength(MAX_MESSAGE_LENGTH, `The preInstallation message must not be longer than ${MAX_MESSAGE_LENGTH} characters`))),
173
+ postInstallation: v.optional(v.pipe(nonEmptyStringValueSchema("postInstallation message"), v.maxLength(MAX_MESSAGE_LENGTH, `The postInstallation message must not be longer than ${MAX_MESSAGE_LENGTH} characters`)))
174
+ });
175
+ /**
176
+ * Schema for installation configuration
177
+ */
178
+ const InstallationSchema = v.object({
179
+ messages: v.optional(MessagesSchema),
180
+ customInstallationSteps: v.pipe(v.optional(v.array(CustomInstallationStepSchema, "Expected an array of custom installation steps")), v.check((input) => {
181
+ const steps = input || [];
182
+ return new Set(steps.map((step) => step.name)).size === steps.length;
183
+ }, "Duplicate step names detected in custom installation steps. Each step must have a unique name."))
184
+ });
237
185
  /**
238
- * This module exports shared error utilities for the AIO Commerce SDK.
239
- * @packageDocumentation
186
+ * Check if config has custom installation settings.
187
+ * @param config - The configuration to check.
240
188
  */
189
+ function hasCustomInstallation(config) {
190
+ return config.installation !== void 0;
191
+ }
241
192
  /**
242
- * Stringify an error to a human-friendly string.
243
- * @param error - The error to stringify.
193
+ * Check if config has custom installation steps.
194
+ * @param config - The configuration to check.
244
195
  */
245
- function stringifyError(error) {
246
- if (error instanceof CommerceSdkValidationError) return error.display();
247
- return error instanceof Error ? error.message : String(error);
196
+ function hasCustomInstallationSteps(config) {
197
+ return Array.isArray(config?.installation?.customInstallationSteps) && config.installation.customInstallationSteps.length > 0;
248
198
  }
249
199
 
250
200
  //#endregion
251
- export { hasExternalEvents as a, hasCustomInstallationSteps as c, hasEventing as i, alphaNumericOrHyphenSchema as l, EventingSchema as n, InstallationSchema as o, hasCommerceEvents as r, hasCustomInstallation as s, stringifyError as t, nonEmptyStringValueSchema as u };
201
+ export { hasCommerceEvents as a, EventingSchema as i, hasCustomInstallation as n, hasEventing as o, hasCustomInstallationSteps as r, hasExternalEvents as s, InstallationSchema as t };
@@ -1,3 +1,2 @@
1
- import "../app-Cx1-6dn0.mjs";
2
- import { A as BranchStep, B as defineBranchStep, C as StepStatus, D as isInProgressState, E as isFailedState, F as LeafStep, H as isBranchStep, I as LeafStepOptions, L as Step, M as ExecutionContext, N as InferStepOutput, O as isSucceededState, P as InstallationContext, R as StepContextFactory, S as InstallationStatus, T as isCompletedState, U as isLeafStep, V as defineLeafStep, _ as FailedInstallationState, a as CustomInstallationStepHandler, b as InstallationError, c as ExecuteWorkflowOptions, d as InstallationHooks, f as StepEvent, g as ExecutionStatus, h as StepSucceededEvent, i as runInstallation, j as BranchStepOptions, k as AnyStep, l as createInitialState, m as StepStartedEvent, n as RunInstallationOptions, o as defineCustomInstallationStep, p as StepFailedEvent, r as createInitialInstallationState, s as CreateInitialStateOptions, t as CreateInitialInstallationStateOptions, u as executeWorkflow, v as InProgressInstallationState, w as SucceededInstallationState, x as InstallationState, y as InstallationData, z as StepMeta } from "../index-Bxr3zvCT.mjs";
3
- export { AnyStep, BranchStep, BranchStepOptions, CreateInitialInstallationStateOptions, CreateInitialStateOptions, CustomInstallationStepHandler, ExecuteWorkflowOptions, ExecutionContext, ExecutionStatus, FailedInstallationState, InProgressInstallationState, InferStepOutput, InstallationContext, InstallationData, InstallationError, InstallationHooks, InstallationState, InstallationStatus, LeafStep, LeafStepOptions, RunInstallationOptions, Step, StepContextFactory, StepEvent, StepFailedEvent, StepMeta, StepStartedEvent, StepStatus, StepSucceededEvent, SucceededInstallationState, createInitialInstallationState, createInitialState, defineBranchStep, defineCustomInstallationStep, defineLeafStep, executeWorkflow, isBranchStep, isCompletedState, isFailedState, isInProgressState, isLeafStep, isSucceededState, runInstallation };
1
+ import { A as BranchStep, B as defineBranchStep, C as StepStatus, D as isInProgressState, E as isFailedState, F as LeafStep, H as isBranchStep, I as LeafStepOptions, L as Step, M as ExecutionContext, N as InferStepOutput, O as isSucceededState, P as InstallationContext, R as StepContextFactory, S as InstallationStatus, T as isCompletedState, U as isLeafStep, V as defineLeafStep, _ as FailedInstallationState, a as CustomInstallationStepHandler, b as InstallationError, c as ExecuteWorkflowOptions, d as InstallationHooks, f as StepEvent, g as ExecutionStatus, h as StepSucceededEvent, i as runInstallation, j as BranchStepOptions, k as AnyStep, l as createInitialState, m as StepStartedEvent, n as RunInstallationOptions, o as defineCustomInstallationStep, p as StepFailedEvent, r as createInitialInstallationState, s as CreateInitialStateOptions, t as CreateInitialInstallationStateOptions, u as executeWorkflow, v as InProgressInstallationState, w as SucceededInstallationState, x as InstallationState, y as InstallationData, z as StepMeta } from "../runner-BD-lItnK.mjs";
2
+ export { AnyStep, BranchStep, BranchStepOptions, type CreateInitialInstallationStateOptions, CreateInitialStateOptions, type CustomInstallationStepHandler, ExecuteWorkflowOptions, ExecutionContext, ExecutionStatus, FailedInstallationState, InProgressInstallationState, InferStepOutput, InstallationContext, InstallationData, InstallationError, InstallationHooks, InstallationState, InstallationStatus, LeafStep, LeafStepOptions, type RunInstallationOptions, Step, StepContextFactory, StepEvent, StepFailedEvent, StepMeta, StepStartedEvent, StepStatus, StepSucceededEvent, SucceededInstallationState, createInitialInstallationState, createInitialState, defineBranchStep, defineCustomInstallationStep, defineLeafStep, executeWorkflow, isBranchStep, isCompletedState, isFailedState, isInProgressState, isLeafStep, isSucceededState, runInstallation };
@@ -1,3 +1,3 @@
1
- import { a as isFailedState, i as isCompletedState, n as runInstallation, o as isInProgressState, r as defineCustomInstallationStep, s as isSucceededState, t as createInitialInstallationState } from "../management-Y7pwEbNI.mjs";
1
+ import { a as isFailedState, i as isCompletedState, n as runInstallation, o as isInProgressState, r as defineCustomInstallationStep, s as isSucceededState, t as createInitialInstallationState } from "../runner-vwAhjD5r.mjs";
2
2
 
3
3
  export { createInitialInstallationState, defineCustomInstallationStep, isCompletedState, isFailedState, isInProgressState, isSucceededState, runInstallation };
@@ -0,0 +1,201 @@
1
+ import { t as validateCommerceAppConfig } from "./validate-DKnju9-R.mjs";
2
+ import { t as stringifyError } from "./error-CMV3IjBz.mjs";
3
+ import { dirname, join, parse } from "path";
4
+ import { existsSync } from "fs";
5
+ import { access, mkdir, readFile } from "fs/promises";
6
+ import { createJiti } from "jiti";
7
+
8
+ //#region source/config/lib/define.ts
9
+ /**
10
+ * Helper to type-safely define the app config.
11
+ * @param config - The app config to define.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { defineConfig } from "@adobe/aio-commerce-lib-app";
16
+ *
17
+ * // In app.commerce.config.js
18
+ * export default defineConfig({
19
+ * // You get autocompletion and type-safety for the config object.
20
+ * businessConfig: { ... }
21
+ * });
22
+ */
23
+ function defineConfig(config) {
24
+ return config;
25
+ }
26
+
27
+ //#endregion
28
+ //#region ../../packages-private/scripting-utils/source/project.ts
29
+ /**
30
+ * This module exports shared project utilities for the AIO Commerce SDK.
31
+ * @packageDocumentation
32
+ */
33
+ /**
34
+ * Find a file by walking up parent directories
35
+ * @param name - The file name to search for (or array of file names)
36
+ * @param options - Search options
37
+ * @returns The path to the file, or undefined if not found
38
+ */
39
+ async function findUp(name, options = {}) {
40
+ const names = Array.isArray(name) ? name : [name];
41
+ const cwd = options.cwd || process.cwd();
42
+ const { root } = parse(cwd);
43
+ const stopAt = options.stopAt || root;
44
+ let currentDir = cwd;
45
+ while (true) {
46
+ for (const fileName of names) {
47
+ const filePath = join(currentDir, fileName);
48
+ try {
49
+ await access(filePath);
50
+ return filePath;
51
+ } catch {}
52
+ }
53
+ if (currentDir === stopAt || currentDir === root) return;
54
+ currentDir = dirname(currentDir);
55
+ }
56
+ }
57
+ /**
58
+ * Find the nearest package.json file in the current working directory or its parents
59
+ * @param cwd The current working directory
60
+ */
61
+ async function findNearestPackageJson(cwd = process.cwd()) {
62
+ const packageJsonPath = await findUp("package.json", { cwd });
63
+ if (!packageJsonPath) return null;
64
+ return packageJsonPath;
65
+ }
66
+ /**
67
+ * Read the package.json file
68
+ * @param cwd The current working directory
69
+ */
70
+ async function readPackageJson(cwd = process.cwd()) {
71
+ const packageJsonPath = await findNearestPackageJson(cwd);
72
+ if (!packageJsonPath) return null;
73
+ return JSON.parse(await readFile(packageJsonPath, "utf-8"));
74
+ }
75
+ /**
76
+ * Check if the current working directory is an ESM project.
77
+ * @param cwd The current working directory
78
+ */
79
+ async function isESM(cwd = process.cwd()) {
80
+ const packageJson = await readPackageJson(cwd);
81
+ if (!packageJson) throw new Error("Could not find a `package.json` file in the current working directory or its parents.");
82
+ return packageJson.type === "module";
83
+ }
84
+ /**
85
+ * Get the root directory of the project
86
+ * @param cwd The current working directory
87
+ */
88
+ async function getProjectRootDirectory(cwd = process.cwd()) {
89
+ const packageJsonPath = await findNearestPackageJson(cwd);
90
+ if (!packageJsonPath) throw new Error("Could not find a the root directory of the project. `package.json` file not found.");
91
+ return dirname(packageJsonPath);
92
+ }
93
+ /**
94
+ * Create the output directory for the given file or folder (relative to the project root)
95
+ * @param fileOrFolder - The file or folder to create
96
+ */
97
+ async function makeOutputDirFor(fileOrFolder) {
98
+ const outputDir = join(await getProjectRootDirectory(), fileOrFolder);
99
+ if (!existsSync(outputDir)) await mkdir(outputDir, { recursive: true });
100
+ return outputDir;
101
+ }
102
+ /** Detect the package manager by checking for lock files */
103
+ async function detectPackageManager(cwd = process.cwd()) {
104
+ const rootDirectory = await getProjectRootDirectory(cwd);
105
+ const lockFileMap = {
106
+ "bun.lockb": "bun",
107
+ "pnpm-lock.yaml": "pnpm",
108
+ "yarn.lock": "yarn",
109
+ "package-lock.json": "npm"
110
+ };
111
+ const lockFileName = Object.keys(lockFileMap).find((name) => existsSync(join(rootDirectory, name)));
112
+ if (!lockFileName) return "npm";
113
+ return lockFileMap[lockFileName];
114
+ }
115
+ /** Get the appropriate exec command based on package manager */
116
+ function getExecCommand(packageManager) {
117
+ return {
118
+ pnpm: "pnpx",
119
+ yarn: "yarn dlx",
120
+ bun: "bunx",
121
+ npm: "npx"
122
+ }[packageManager];
123
+ }
124
+
125
+ //#endregion
126
+ //#region source/config/lib/parser.ts
127
+ const jiti = createJiti(import.meta.url);
128
+ const configPaths = Object.freeze([
129
+ "app.commerce.config.js",
130
+ "app.commerce.config.ts",
131
+ "app.commerce.config.cjs",
132
+ "app.commerce.config.mjs",
133
+ "app.commerce.config.mts",
134
+ "app.commerce.config.cts"
135
+ ]);
136
+ /**
137
+ * Try to find (up to the nearest package.json file) the app config file.
138
+ *
139
+ * Searches for config files in the following order of priority:
140
+ * 1. `app.commerce.config.js` - JavaScript (CommonJS or ESM)
141
+ * 2. `app.commerce.config.ts` - TypeScript
142
+ * 3. `app.commerce.config.cjs` - CommonJS
143
+ * 4. `app.commerce.config.mjs` - ES Module
144
+ * 5. `app.commerce.config.mts` - ES Module TypeScript
145
+ * 6. `app.commerce.config.cts` - CommonJS TypeScript
146
+ *
147
+ * @param cwd The current working directory
148
+ * @returns The path to the config file, or null if not found
149
+ */
150
+ async function resolveCommerceAppConfig(cwd = process.cwd()) {
151
+ const packageJsonPath = await findNearestPackageJson(cwd);
152
+ if (!packageJsonPath) return null;
153
+ const rootDirectory = dirname(packageJsonPath);
154
+ for (const configPath of configPaths) {
155
+ const configFilePath = await findUp(configPath, {
156
+ cwd,
157
+ stopAt: rootDirectory
158
+ });
159
+ if (configFilePath) return configFilePath;
160
+ }
161
+ return null;
162
+ }
163
+ /**
164
+ * Read the commerce app config file as-is, without validating it.
165
+ *
166
+ * Supports multiple config file formats (see {@link resolveCommerceAppConfig} for the list).
167
+ * The config file must export a default export with the configuration object.
168
+ *
169
+ * @param cwd The current working directory
170
+ * @returns The raw config object from the file
171
+ * @throws {Error} If no config file is found or if the file doesn't export a default export
172
+ */
173
+ async function readCommerceAppConfig(cwd = process.cwd()) {
174
+ const configFilePath = await resolveCommerceAppConfig(cwd);
175
+ if (!configFilePath) throw new Error("Could not find a commerce app config file in the current working directory or its parents.");
176
+ let config = null;
177
+ try {
178
+ config = await jiti.import(configFilePath);
179
+ } catch (error) {
180
+ const message = stringifyError(error);
181
+ throw new Error(`Failed to read commerce app config file at ${configFilePath}: ${message}`, { cause: error });
182
+ }
183
+ if (!(config && "default" in config) || config.default === void 0 || config.default === null || typeof config.default === "object" && Object.keys(config.default).length === 0) throw new Error("Commerce app config file does not export a default export. Make sure you use `export default` or `module.exports = { /* your config */ }`");
184
+ return config.default;
185
+ }
186
+ /**
187
+ * Read the commerce app config file and parse its contents into its schema.
188
+ *
189
+ * Supports multiple config file formats (see {@link resolveCommerceAppConfig} for the list).
190
+ * The config file must export a default export with the configuration object.
191
+ *
192
+ * @param cwd The current working directory
193
+ * @returns The validated and parsed config object
194
+ * @throws {Error} If no config file is found, if the file doesn't export a default export, or if validation fails
195
+ */
196
+ async function parseCommerceAppConfig(cwd = process.cwd()) {
197
+ return validateCommerceAppConfig(await readCommerceAppConfig(cwd));
198
+ }
199
+
200
+ //#endregion
201
+ export { findNearestPackageJson as a, isESM as c, defineConfig as d, detectPackageManager as i, makeOutputDirFor as l, readCommerceAppConfig as n, getExecCommand as o, resolveCommerceAppConfig as r, getProjectRootDirectory as s, parseCommerceAppConfig as t, readPackageJson as u };