@adobe/aio-commerce-lib-webhooks 1.1.2 → 1.2.0-beta-20260714082406

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # @adobe/aio-commerce-lib-webhooks
2
2
 
3
+ ## 1.2.0-beta-20260714082406
4
+ ### Minor Changes
5
+
6
+
7
+
8
+ - [#563](https://github.com/adobe/aio-commerce-sdk/pull/563) [`19400fb`](https://github.com/adobe/aio-commerce-sdk/commit/19400fbdfc03c5bbfc30f995a2acdd4272c5e032) Thanks [@obarcelonap](https://github.com/obarcelonap)! - Add webhook response helpers to identify webhook success responses and determine whether webhook action responses represent successful outcomes.
9
+
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies [[`19400fb`](https://github.com/adobe/aio-commerce-sdk/commit/19400fbdfc03c5bbfc30f995a2acdd4272c5e032), [`ce7768e`](https://github.com/adobe/aio-commerce-sdk/commit/ce7768e0ddc6ca35ad6ccec60f584c8bb5a743f0), [`4396a64`](https://github.com/adobe/aio-commerce-sdk/commit/4396a647ad22dba063cdf03a16e04aef9387212f), [`e85bec4`](https://github.com/adobe/aio-commerce-sdk/commit/e85bec40f1eaa91dd6bb7bc6954b2ecfc3ea4029), [`413da36`](https://github.com/adobe/aio-commerce-sdk/commit/413da36dcd83e5a41c194f5af50611097659e725)]:
14
+ - @adobe/aio-commerce-lib-core@1.2.0-beta-20260714082406
15
+ - @adobe/aio-commerce-lib-api@1.3.0-beta-20260714082406
16
+
3
17
  ## 1.1.2
4
18
 
5
19
  ### Patch Changes
@@ -71,8 +71,8 @@ const WebhookHeaderSchema = valibot.object({
71
71
  const DeveloperConsoleOAuthSchema = valibot.object({
72
72
  client_id: nonEmptyString("client_id"),
73
73
  client_secret: nonEmptyString("client_secret"),
74
- org_id: nonEmptyString("org_id"),
75
- environment: optionalString("environment")
74
+ environment: optionalString("environment"),
75
+ org_id: nonEmptyString("org_id")
76
76
  });
77
77
  /**
78
78
  * Schema for the webhook payload sent to POST /webhooks/subscribe.
@@ -80,33 +80,33 @@ const DeveloperConsoleOAuthSchema = valibot.object({
80
80
  * Required fields per the Commerce API: webhook_method, webhook_type, batch_name, hook_name, url.
81
81
  */
82
82
  const WebhookSubscribeParamsSchema = valibot.object({
83
- webhook_method: nonEmptyString("webhook_method"),
84
- webhook_type: nonEmptyString("webhook_type"),
85
83
  batch_name: nonEmptyString("batch_name"),
86
84
  batch_order: valibot.optional(valibot.number()),
85
+ developer_console_oauth: valibot.optional(DeveloperConsoleOAuthSchema),
86
+ fallback_error_message: optionalString("fallback_error_message"),
87
+ fields: valibot.optional(valibot.array(WebhookFieldSchema, "Expected an array of field objects")),
88
+ headers: valibot.optional(valibot.array(WebhookHeaderSchema, "Expected an array of header objects")),
87
89
  hook_name: nonEmptyString("hook_name"),
88
- url: nonEmptyString("url"),
90
+ method: optionalString("method"),
89
91
  priority: valibot.optional(valibot.number()),
90
92
  required: valibot.optional(valibot.boolean()),
93
+ rules: valibot.optional(valibot.array(WebhookRuleSchema, "Expected an array of rule objects")),
91
94
  soft_timeout: valibot.optional(valibot.number()),
92
95
  timeout: valibot.optional(valibot.number()),
93
- method: optionalString("method"),
94
- fallback_error_message: optionalString("fallback_error_message"),
95
96
  ttl: valibot.optional(valibot.number()),
96
- fields: valibot.optional(valibot.array(WebhookFieldSchema, "Expected an array of field objects")),
97
- rules: valibot.optional(valibot.array(WebhookRuleSchema, "Expected an array of rule objects")),
98
- headers: valibot.optional(valibot.array(WebhookHeaderSchema, "Expected an array of header objects")),
99
- developer_console_oauth: valibot.optional(DeveloperConsoleOAuthSchema)
97
+ url: nonEmptyString("url"),
98
+ webhook_method: nonEmptyString("webhook_method"),
99
+ webhook_type: nonEmptyString("webhook_type")
100
100
  });
101
101
  /**
102
102
  * Schema for the parameters sent to POST /webhooks/unsubscribe.
103
103
  * Required: webhook_method, webhook_type, batch_name, hook_name.
104
104
  */
105
105
  const WebhookUnsubscribeParamsSchema = valibot.object({
106
- webhook_method: nonEmptyString("webhook_method"),
107
- webhook_type: nonEmptyString("webhook_type"),
108
106
  batch_name: nonEmptyString("batch_name"),
109
- hook_name: nonEmptyString("hook_name")
107
+ hook_name: nonEmptyString("hook_name"),
108
+ webhook_method: nonEmptyString("webhook_method"),
109
+ webhook_type: nonEmptyString("webhook_type")
110
110
  });
111
111
 
112
112
  //#endregion
@@ -176,10 +176,10 @@ function getSupportedWebhookList(httpClient, fetchOptions) {
176
176
  */
177
177
  function createCommerceWebhooksApiClient(params) {
178
178
  return _adobe_aio_commerce_lib_api.ApiClient.create(new _adobe_aio_commerce_lib_api.AdobeCommerceHttpClient(params), {
179
+ getSupportedWebhookList,
179
180
  getWebhookList,
180
181
  subscribeWebhook,
181
- unsubscribeWebhook,
182
- getSupportedWebhookList
182
+ unsubscribeWebhook
183
183
  });
184
184
  }
185
185
  /**
@@ -23,48 +23,48 @@ import * as v from "valibot";
23
23
  * Required fields per the Commerce API: webhook_method, webhook_type, batch_name, hook_name, url.
24
24
  */
25
25
  declare const WebhookSubscribeParamsSchema: v.ObjectSchema<{
26
- readonly webhook_method: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
27
- readonly webhook_type: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
28
26
  readonly batch_name: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
29
27
  readonly batch_order: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
30
- readonly hook_name: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
31
- readonly url: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
32
- readonly priority: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
33
- readonly required: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
34
- readonly soft_timeout: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
35
- readonly timeout: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
36
- readonly method: v.OptionalSchema<v.StringSchema<`Expected a string for ${string}`>, undefined>;
28
+ readonly developer_console_oauth: v.OptionalSchema<v.ObjectSchema<{
29
+ readonly client_id: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
30
+ readonly client_secret: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
31
+ readonly environment: v.OptionalSchema<v.StringSchema<`Expected a string for ${string}`>, undefined>;
32
+ readonly org_id: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
33
+ }, undefined>, undefined>;
37
34
  readonly fallback_error_message: v.OptionalSchema<v.StringSchema<`Expected a string for ${string}`>, undefined>;
38
- readonly ttl: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
39
35
  readonly fields: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
40
36
  readonly name: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
41
37
  readonly source: v.OptionalSchema<v.StringSchema<`Expected a string for ${string}`>, undefined>;
42
38
  }, undefined>, "Expected an array of field objects">, undefined>;
39
+ readonly headers: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
40
+ readonly name: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
41
+ readonly value: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
42
+ }, undefined>, "Expected an array of header objects">, undefined>;
43
+ readonly hook_name: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
44
+ readonly method: v.OptionalSchema<v.StringSchema<`Expected a string for ${string}`>, undefined>;
45
+ readonly priority: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
46
+ readonly required: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
43
47
  readonly rules: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
44
48
  readonly field: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
45
49
  readonly operator: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
46
50
  readonly value: v.StringSchema<"Expected a string for rule value">;
47
51
  }, undefined>, "Expected an array of rule objects">, undefined>;
48
- readonly headers: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
49
- readonly name: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
50
- readonly value: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
51
- }, undefined>, "Expected an array of header objects">, undefined>;
52
- readonly developer_console_oauth: v.OptionalSchema<v.ObjectSchema<{
53
- readonly client_id: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
54
- readonly client_secret: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
55
- readonly org_id: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
56
- readonly environment: v.OptionalSchema<v.StringSchema<`Expected a string for ${string}`>, undefined>;
57
- }, undefined>, undefined>;
52
+ readonly soft_timeout: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
53
+ readonly timeout: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
54
+ readonly ttl: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
55
+ readonly url: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
56
+ readonly webhook_method: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
57
+ readonly webhook_type: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
58
58
  }, undefined>;
59
59
  /**
60
60
  * Schema for the parameters sent to POST /webhooks/unsubscribe.
61
61
  * Required: webhook_method, webhook_type, batch_name, hook_name.
62
62
  */
63
63
  declare const WebhookUnsubscribeParamsSchema: v.ObjectSchema<{
64
- readonly webhook_method: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
65
- readonly webhook_type: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
66
64
  readonly batch_name: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
67
65
  readonly hook_name: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
66
+ readonly webhook_method: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
67
+ readonly webhook_type: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
68
68
  }, undefined>;
69
69
  /**
70
70
  * The parameters for POST /webhooks/subscribe.
@@ -178,10 +178,10 @@ declare function getSupportedWebhookList(httpClient: AdobeCommerceHttpClient, fe
178
178
  * @param params - The parameters to build the Commerce HTTP client.
179
179
  */
180
180
  declare function createCommerceWebhooksApiClient(params: CommerceHttpClientParams): import("@adobe/aio-commerce-lib-api").ApiClientRecord<AdobeCommerceHttpClient, {
181
+ getSupportedWebhookList: typeof getSupportedWebhookList;
181
182
  getWebhookList: typeof getWebhookList;
182
183
  subscribeWebhook: typeof subscribeWebhook;
183
184
  unsubscribeWebhook: typeof unsubscribeWebhook;
184
- getSupportedWebhookList: typeof getSupportedWebhookList;
185
185
  }>;
186
186
  /**
187
187
  * An API client for the Commerce Webhooks API.
@@ -13,8 +13,78 @@
13
13
  */
14
14
 
15
15
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
16
+ let _adobe_aio_commerce_lib_api_utils = require("@adobe/aio-commerce-lib-api/utils");
16
17
  let _adobe_aio_commerce_lib_core_responses = require("@adobe/aio-commerce-lib-core/responses");
17
18
 
19
+ //#region source/responses/operations/types.ts
20
+ function isRecord$1(value) {
21
+ return typeof value === "object" && value !== null && !Array.isArray(value);
22
+ }
23
+ /**
24
+ * Determines whether a value is a webhook operation response.
25
+ *
26
+ * @param body - Value to inspect.
27
+ * @returns True when the value matches one of the webhook operation response shapes.
28
+ */
29
+ function isWebhookOperationResponse(body) {
30
+ if (!isRecord$1(body)) return false;
31
+ const { op, path } = body;
32
+ if (op === "success" || op === "exception") return true;
33
+ if (op === "add" || op === "replace") return typeof path === "string" && "value" in body;
34
+ return op === "remove" && typeof path === "string";
35
+ }
36
+ /**
37
+ * Determines whether a value is an array of webhook operation responses.
38
+ *
39
+ * @param body - Value to inspect.
40
+ * @returns True when every array item matches a webhook operation response shape.
41
+ */
42
+ function isWebhookOperationResponseArray(body) {
43
+ return Array.isArray(body) && body.every(isWebhookOperationResponse);
44
+ }
45
+
46
+ //#endregion
47
+ //#region source/responses/types.ts
48
+ function isRecord(value) {
49
+ return typeof value === "object" && value !== null && !Array.isArray(value);
50
+ }
51
+ /**
52
+ * Determines whether a value is a successful SDK response containing webhook operation response body data.
53
+ *
54
+ * @param response - Value to inspect.
55
+ * @returns True when the value matches the webhook success response shape.
56
+ */
57
+ function isWebhookSuccessResponse(response) {
58
+ return isRecord(response) && response.type === "success" && response.statusCode === _adobe_aio_commerce_lib_api_utils.HTTP_OK && (response.body === void 0 || isWebhookOperationResponse(response.body) || isWebhookOperationResponseArray(response.body));
59
+ }
60
+
61
+ //#endregion
62
+ //#region source/responses/helpers.ts
63
+ /**
64
+ * Determines whether a webhook action's result represents a successful outcome.
65
+ * Adobe Commerce webhooks always respond with HTTP 200, even when the handler
66
+ * wants to block the triggering process, so the actual outcome is only visible
67
+ * in the response body's `op` field (`op: "exception"` signals a failure).
68
+ *
69
+ * @param result - The result of the instrumented webhook action.
70
+ * @returns True if the webhook response is successful, false otherwise.
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * import { isWebhookSuccessful } from "@adobe/aio-commerce-lib-webhooks/responses";
75
+ *
76
+ * const result = await runWebhookAction(params);
77
+ * span.setStatus(isWebhookSuccessful(result) ? { code: SpanStatusCode.OK } : { code: SpanStatusCode.ERROR });
78
+ * ```
79
+ */
80
+ function isWebhookSuccessful(result) {
81
+ if (!isWebhookSuccessResponse(result)) return false;
82
+ if (!result.body) return true;
83
+ if (Array.isArray(result.body)) return result.body.every((operation) => operation.op !== "exception");
84
+ return result.body.op !== "exception";
85
+ }
86
+
87
+ //#endregion
18
88
  //#region source/responses/operations/presets.ts
19
89
  /**
20
90
  * Creates a success operation response
@@ -142,6 +212,8 @@ function ok(operations) {
142
212
  //#endregion
143
213
  exports.addOperation = addOperation;
144
214
  exports.exceptionOperation = exceptionOperation;
215
+ exports.isWebhookSuccessResponse = isWebhookSuccessResponse;
216
+ exports.isWebhookSuccessful = isWebhookSuccessful;
145
217
  exports.ok = ok;
146
218
  exports.removeOperation = removeOperation;
147
219
  exports.replaceOperation = replaceOperation;
@@ -13,7 +13,28 @@
13
13
  */
14
14
 
15
15
  import { SuccessResponse } from "@adobe/aio-commerce-lib-core/responses";
16
+ import { HTTP_OK } from "@adobe/aio-commerce-lib-api/utils";
16
17
 
18
+ //#region source/responses/helpers.d.ts
19
+ /**
20
+ * Determines whether a webhook action's result represents a successful outcome.
21
+ * Adobe Commerce webhooks always respond with HTTP 200, even when the handler
22
+ * wants to block the triggering process, so the actual outcome is only visible
23
+ * in the response body's `op` field (`op: "exception"` signals a failure).
24
+ *
25
+ * @param result - The result of the instrumented webhook action.
26
+ * @returns True if the webhook response is successful, false otherwise.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * import { isWebhookSuccessful } from "@adobe/aio-commerce-lib-webhooks/responses";
31
+ *
32
+ * const result = await runWebhookAction(params);
33
+ * span.setStatus(isWebhookSuccessful(result) ? { code: SpanStatusCode.OK } : { code: SpanStatusCode.ERROR });
34
+ * ```
35
+ */
36
+ declare function isWebhookSuccessful(result: unknown): boolean;
37
+ //#endregion
17
38
  //#region source/responses/operations/types.d.ts
18
39
  /**
19
40
  * Success operation response
@@ -172,4 +193,20 @@ declare const removeOperation: (path: string) => RemoveOperation;
172
193
  */
173
194
  declare function ok<TValue = unknown>(operations: WebhookOperationResponse<TValue> | WebhookOperationResponse[]): SuccessResponse;
174
195
  //#endregion
175
- export { type AddOperation, type ExceptionOperation, type RemoveOperation, type ReplaceOperation, type SuccessOperation, type WebhookOperationResponse, addOperation, exceptionOperation, ok, removeOperation, replaceOperation, successOperation };
196
+ //#region source/responses/types.d.ts
197
+ /**
198
+ * Successful SDK response containing webhook operation response body data.
199
+ */
200
+ type WebhookSuccessResponse = Omit<SuccessResponse, "body" | "statusCode"> & {
201
+ body?: WebhookOperationResponse | WebhookOperationResponse[];
202
+ statusCode: typeof HTTP_OK;
203
+ };
204
+ /**
205
+ * Determines whether a value is a successful SDK response containing webhook operation response body data.
206
+ *
207
+ * @param response - Value to inspect.
208
+ * @returns True when the value matches the webhook success response shape.
209
+ */
210
+ declare function isWebhookSuccessResponse(response: unknown): response is WebhookSuccessResponse;
211
+ //#endregion
212
+ export { type AddOperation, type ExceptionOperation, type RemoveOperation, type ReplaceOperation, type SuccessOperation, type WebhookOperationResponse, type WebhookSuccessResponse, addOperation, exceptionOperation, isWebhookSuccessResponse, isWebhookSuccessful, ok, removeOperation, replaceOperation, successOperation };
@@ -23,48 +23,48 @@ import { Options } from "ky";
23
23
  * Required fields per the Commerce API: webhook_method, webhook_type, batch_name, hook_name, url.
24
24
  */
25
25
  declare const WebhookSubscribeParamsSchema: v.ObjectSchema<{
26
- readonly webhook_method: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
27
- readonly webhook_type: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
28
26
  readonly batch_name: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
29
27
  readonly batch_order: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
30
- readonly hook_name: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
31
- readonly url: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
32
- readonly priority: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
33
- readonly required: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
34
- readonly soft_timeout: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
35
- readonly timeout: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
36
- readonly method: v.OptionalSchema<v.StringSchema<`Expected a string for ${string}`>, undefined>;
28
+ readonly developer_console_oauth: v.OptionalSchema<v.ObjectSchema<{
29
+ readonly client_id: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
30
+ readonly client_secret: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
31
+ readonly environment: v.OptionalSchema<v.StringSchema<`Expected a string for ${string}`>, undefined>;
32
+ readonly org_id: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
33
+ }, undefined>, undefined>;
37
34
  readonly fallback_error_message: v.OptionalSchema<v.StringSchema<`Expected a string for ${string}`>, undefined>;
38
- readonly ttl: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
39
35
  readonly fields: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
40
36
  readonly name: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
41
37
  readonly source: v.OptionalSchema<v.StringSchema<`Expected a string for ${string}`>, undefined>;
42
38
  }, undefined>, "Expected an array of field objects">, undefined>;
39
+ readonly headers: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
40
+ readonly name: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
41
+ readonly value: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
42
+ }, undefined>, "Expected an array of header objects">, undefined>;
43
+ readonly hook_name: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
44
+ readonly method: v.OptionalSchema<v.StringSchema<`Expected a string for ${string}`>, undefined>;
45
+ readonly priority: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
46
+ readonly required: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
43
47
  readonly rules: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
44
48
  readonly field: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
45
49
  readonly operator: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
46
50
  readonly value: v.StringSchema<"Expected a string for rule value">;
47
51
  }, undefined>, "Expected an array of rule objects">, undefined>;
48
- readonly headers: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
49
- readonly name: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
50
- readonly value: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
51
- }, undefined>, "Expected an array of header objects">, undefined>;
52
- readonly developer_console_oauth: v.OptionalSchema<v.ObjectSchema<{
53
- readonly client_id: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
54
- readonly client_secret: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
55
- readonly org_id: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
56
- readonly environment: v.OptionalSchema<v.StringSchema<`Expected a string for ${string}`>, undefined>;
57
- }, undefined>, undefined>;
52
+ readonly soft_timeout: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
53
+ readonly timeout: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
54
+ readonly ttl: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
55
+ readonly url: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
56
+ readonly webhook_method: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
57
+ readonly webhook_type: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
58
58
  }, undefined>;
59
59
  /**
60
60
  * Schema for the parameters sent to POST /webhooks/unsubscribe.
61
61
  * Required: webhook_method, webhook_type, batch_name, hook_name.
62
62
  */
63
63
  declare const WebhookUnsubscribeParamsSchema: v.ObjectSchema<{
64
- readonly webhook_method: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
65
- readonly webhook_type: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
66
64
  readonly batch_name: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
67
65
  readonly hook_name: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
66
+ readonly webhook_method: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
67
+ readonly webhook_type: v.SchemaWithPipe<readonly [v.StringSchema<`Expected a string for ${string}`>, v.NonEmptyAction<string, `${string} must not be empty`>]>;
68
68
  }, undefined>;
69
69
  /**
70
70
  * The parameters for POST /webhooks/subscribe.
@@ -178,10 +178,10 @@ declare function getSupportedWebhookList(httpClient: AdobeCommerceHttpClient, fe
178
178
  * @param params - The parameters to build the Commerce HTTP client.
179
179
  */
180
180
  declare function createCommerceWebhooksApiClient(params: CommerceHttpClientParams): import("@adobe/aio-commerce-lib-api").ApiClientRecord<AdobeCommerceHttpClient, {
181
+ getSupportedWebhookList: typeof getSupportedWebhookList;
181
182
  getWebhookList: typeof getWebhookList;
182
183
  subscribeWebhook: typeof subscribeWebhook;
183
184
  unsubscribeWebhook: typeof unsubscribeWebhook;
184
- getSupportedWebhookList: typeof getSupportedWebhookList;
185
185
  }>;
186
186
  /**
187
187
  * An API client for the Commerce Webhooks API.
@@ -42,8 +42,8 @@ const WebhookHeaderSchema = v.object({
42
42
  const DeveloperConsoleOAuthSchema = v.object({
43
43
  client_id: nonEmptyString("client_id"),
44
44
  client_secret: nonEmptyString("client_secret"),
45
- org_id: nonEmptyString("org_id"),
46
- environment: optionalString("environment")
45
+ environment: optionalString("environment"),
46
+ org_id: nonEmptyString("org_id")
47
47
  });
48
48
  /**
49
49
  * Schema for the webhook payload sent to POST /webhooks/subscribe.
@@ -51,33 +51,33 @@ const DeveloperConsoleOAuthSchema = v.object({
51
51
  * Required fields per the Commerce API: webhook_method, webhook_type, batch_name, hook_name, url.
52
52
  */
53
53
  const WebhookSubscribeParamsSchema = v.object({
54
- webhook_method: nonEmptyString("webhook_method"),
55
- webhook_type: nonEmptyString("webhook_type"),
56
54
  batch_name: nonEmptyString("batch_name"),
57
55
  batch_order: v.optional(v.number()),
56
+ developer_console_oauth: v.optional(DeveloperConsoleOAuthSchema),
57
+ fallback_error_message: optionalString("fallback_error_message"),
58
+ fields: v.optional(v.array(WebhookFieldSchema, "Expected an array of field objects")),
59
+ headers: v.optional(v.array(WebhookHeaderSchema, "Expected an array of header objects")),
58
60
  hook_name: nonEmptyString("hook_name"),
59
- url: nonEmptyString("url"),
61
+ method: optionalString("method"),
60
62
  priority: v.optional(v.number()),
61
63
  required: v.optional(v.boolean()),
64
+ rules: v.optional(v.array(WebhookRuleSchema, "Expected an array of rule objects")),
62
65
  soft_timeout: v.optional(v.number()),
63
66
  timeout: v.optional(v.number()),
64
- method: optionalString("method"),
65
- fallback_error_message: optionalString("fallback_error_message"),
66
67
  ttl: v.optional(v.number()),
67
- fields: v.optional(v.array(WebhookFieldSchema, "Expected an array of field objects")),
68
- rules: v.optional(v.array(WebhookRuleSchema, "Expected an array of rule objects")),
69
- headers: v.optional(v.array(WebhookHeaderSchema, "Expected an array of header objects")),
70
- developer_console_oauth: v.optional(DeveloperConsoleOAuthSchema)
68
+ url: nonEmptyString("url"),
69
+ webhook_method: nonEmptyString("webhook_method"),
70
+ webhook_type: nonEmptyString("webhook_type")
71
71
  });
72
72
  /**
73
73
  * Schema for the parameters sent to POST /webhooks/unsubscribe.
74
74
  * Required: webhook_method, webhook_type, batch_name, hook_name.
75
75
  */
76
76
  const WebhookUnsubscribeParamsSchema = v.object({
77
- webhook_method: nonEmptyString("webhook_method"),
78
- webhook_type: nonEmptyString("webhook_type"),
79
77
  batch_name: nonEmptyString("batch_name"),
80
- hook_name: nonEmptyString("hook_name")
78
+ hook_name: nonEmptyString("hook_name"),
79
+ webhook_method: nonEmptyString("webhook_method"),
80
+ webhook_type: nonEmptyString("webhook_type")
81
81
  });
82
82
 
83
83
  //#endregion
@@ -147,10 +147,10 @@ function getSupportedWebhookList(httpClient, fetchOptions) {
147
147
  */
148
148
  function createCommerceWebhooksApiClient(params) {
149
149
  return ApiClient.create(new AdobeCommerceHttpClient(params), {
150
+ getSupportedWebhookList,
150
151
  getWebhookList,
151
152
  subscribeWebhook,
152
- unsubscribeWebhook,
153
- getSupportedWebhookList
153
+ unsubscribeWebhook
154
154
  });
155
155
  }
156
156
  /**
@@ -12,8 +12,29 @@
12
12
  * governing permissions and limitations under the License.
13
13
  */
14
14
 
15
+ import { HTTP_OK } from "@adobe/aio-commerce-lib-api/utils";
15
16
  import { SuccessResponse } from "@adobe/aio-commerce-lib-core/responses";
16
17
 
18
+ //#region source/responses/helpers.d.ts
19
+ /**
20
+ * Determines whether a webhook action's result represents a successful outcome.
21
+ * Adobe Commerce webhooks always respond with HTTP 200, even when the handler
22
+ * wants to block the triggering process, so the actual outcome is only visible
23
+ * in the response body's `op` field (`op: "exception"` signals a failure).
24
+ *
25
+ * @param result - The result of the instrumented webhook action.
26
+ * @returns True if the webhook response is successful, false otherwise.
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * import { isWebhookSuccessful } from "@adobe/aio-commerce-lib-webhooks/responses";
31
+ *
32
+ * const result = await runWebhookAction(params);
33
+ * span.setStatus(isWebhookSuccessful(result) ? { code: SpanStatusCode.OK } : { code: SpanStatusCode.ERROR });
34
+ * ```
35
+ */
36
+ declare function isWebhookSuccessful(result: unknown): boolean;
37
+ //#endregion
17
38
  //#region source/responses/operations/types.d.ts
18
39
  /**
19
40
  * Success operation response
@@ -172,4 +193,20 @@ declare const removeOperation: (path: string) => RemoveOperation;
172
193
  */
173
194
  declare function ok<TValue = unknown>(operations: WebhookOperationResponse<TValue> | WebhookOperationResponse[]): SuccessResponse;
174
195
  //#endregion
175
- export { type AddOperation, type ExceptionOperation, type RemoveOperation, type ReplaceOperation, type SuccessOperation, type WebhookOperationResponse, addOperation, exceptionOperation, ok, removeOperation, replaceOperation, successOperation };
196
+ //#region source/responses/types.d.ts
197
+ /**
198
+ * Successful SDK response containing webhook operation response body data.
199
+ */
200
+ type WebhookSuccessResponse = Omit<SuccessResponse, "body" | "statusCode"> & {
201
+ body?: WebhookOperationResponse | WebhookOperationResponse[];
202
+ statusCode: typeof HTTP_OK;
203
+ };
204
+ /**
205
+ * Determines whether a value is a successful SDK response containing webhook operation response body data.
206
+ *
207
+ * @param response - Value to inspect.
208
+ * @returns True when the value matches the webhook success response shape.
209
+ */
210
+ declare function isWebhookSuccessResponse(response: unknown): response is WebhookSuccessResponse;
211
+ //#endregion
212
+ export { type AddOperation, type ExceptionOperation, type RemoveOperation, type ReplaceOperation, type SuccessOperation, type WebhookOperationResponse, type WebhookSuccessResponse, addOperation, exceptionOperation, isWebhookSuccessResponse, isWebhookSuccessful, ok, removeOperation, replaceOperation, successOperation };
@@ -12,8 +12,78 @@
12
12
  * governing permissions and limitations under the License.
13
13
  */
14
14
 
15
+ import { HTTP_OK } from "@adobe/aio-commerce-lib-api/utils";
15
16
  import { ok as ok$1 } from "@adobe/aio-commerce-lib-core/responses";
16
17
 
18
+ //#region source/responses/operations/types.ts
19
+ function isRecord$1(value) {
20
+ return typeof value === "object" && value !== null && !Array.isArray(value);
21
+ }
22
+ /**
23
+ * Determines whether a value is a webhook operation response.
24
+ *
25
+ * @param body - Value to inspect.
26
+ * @returns True when the value matches one of the webhook operation response shapes.
27
+ */
28
+ function isWebhookOperationResponse(body) {
29
+ if (!isRecord$1(body)) return false;
30
+ const { op, path } = body;
31
+ if (op === "success" || op === "exception") return true;
32
+ if (op === "add" || op === "replace") return typeof path === "string" && "value" in body;
33
+ return op === "remove" && typeof path === "string";
34
+ }
35
+ /**
36
+ * Determines whether a value is an array of webhook operation responses.
37
+ *
38
+ * @param body - Value to inspect.
39
+ * @returns True when every array item matches a webhook operation response shape.
40
+ */
41
+ function isWebhookOperationResponseArray(body) {
42
+ return Array.isArray(body) && body.every(isWebhookOperationResponse);
43
+ }
44
+
45
+ //#endregion
46
+ //#region source/responses/types.ts
47
+ function isRecord(value) {
48
+ return typeof value === "object" && value !== null && !Array.isArray(value);
49
+ }
50
+ /**
51
+ * Determines whether a value is a successful SDK response containing webhook operation response body data.
52
+ *
53
+ * @param response - Value to inspect.
54
+ * @returns True when the value matches the webhook success response shape.
55
+ */
56
+ function isWebhookSuccessResponse(response) {
57
+ return isRecord(response) && response.type === "success" && response.statusCode === HTTP_OK && (response.body === void 0 || isWebhookOperationResponse(response.body) || isWebhookOperationResponseArray(response.body));
58
+ }
59
+
60
+ //#endregion
61
+ //#region source/responses/helpers.ts
62
+ /**
63
+ * Determines whether a webhook action's result represents a successful outcome.
64
+ * Adobe Commerce webhooks always respond with HTTP 200, even when the handler
65
+ * wants to block the triggering process, so the actual outcome is only visible
66
+ * in the response body's `op` field (`op: "exception"` signals a failure).
67
+ *
68
+ * @param result - The result of the instrumented webhook action.
69
+ * @returns True if the webhook response is successful, false otherwise.
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * import { isWebhookSuccessful } from "@adobe/aio-commerce-lib-webhooks/responses";
74
+ *
75
+ * const result = await runWebhookAction(params);
76
+ * span.setStatus(isWebhookSuccessful(result) ? { code: SpanStatusCode.OK } : { code: SpanStatusCode.ERROR });
77
+ * ```
78
+ */
79
+ function isWebhookSuccessful(result) {
80
+ if (!isWebhookSuccessResponse(result)) return false;
81
+ if (!result.body) return true;
82
+ if (Array.isArray(result.body)) return result.body.every((operation) => operation.op !== "exception");
83
+ return result.body.op !== "exception";
84
+ }
85
+
86
+ //#endregion
17
87
  //#region source/responses/operations/presets.ts
18
88
  /**
19
89
  * Creates a success operation response
@@ -139,4 +209,4 @@ function ok(operations) {
139
209
  }
140
210
 
141
211
  //#endregion
142
- export { addOperation, exceptionOperation, ok, removeOperation, replaceOperation, successOperation };
212
+ export { addOperation, exceptionOperation, isWebhookSuccessResponse, isWebhookSuccessful, ok, removeOperation, replaceOperation, successOperation };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@adobe/aio-commerce-lib-webhooks",
3
3
  "type": "module",
4
4
  "author": "Adobe Inc.",
5
- "version": "1.1.2",
5
+ "version": "1.2.0-beta-20260714082406",
6
6
  "private": false,
7
7
  "engines": {
8
8
  "node": ">=22 <=24"
@@ -64,8 +64,8 @@
64
64
  "dependencies": {
65
65
  "ky": "^1.9.0",
66
66
  "valibot": "^1.1.0",
67
- "@adobe/aio-commerce-lib-api": "1.2.1",
68
- "@adobe/aio-commerce-lib-core": "1.1.1"
67
+ "@adobe/aio-commerce-lib-api": "1.3.0-beta-20260714082406",
68
+ "@adobe/aio-commerce-lib-core": "1.2.0-beta-20260714082406"
69
69
  },
70
70
  "devDependencies": {
71
71
  "typescript": "^6.0.0",
@@ -73,7 +73,7 @@
73
73
  "@aio-commerce-sdk/config-tsdown": "1.0.1",
74
74
  "@aio-commerce-sdk/config-typescript": "1.0.0",
75
75
  "@aio-commerce-sdk/config-vitest": "1.0.0",
76
- "@aio-commerce-sdk/scripting-utils": "0.3.3",
76
+ "@aio-commerce-sdk/scripting-utils": "0.3.4-beta-20260714082406",
77
77
  "@aio-commerce-sdk/scripts": "0.1.0"
78
78
  },
79
79
  "sideEffects": false,