@adobe-commerce/aio-toolkit 1.0.2 → 1.0.4

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/dist/index.js CHANGED
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  // src/index.ts
32
32
  var index_exports = {};
33
33
  __export(index_exports, {
34
+ AdminUiSdk: () => AdminUiSdk,
34
35
  AdobeAuth: () => adobe_auth_default,
35
36
  AdobeCommerceClient: () => adobe_commerce_client_default,
36
37
  BasicAuthConnection: () => basic_auth_connection_default,
@@ -54,11 +55,19 @@ __export(index_exports, {
54
55
  OpenwhiskAction: () => openwhisk_action_default,
55
56
  Parameters: () => parameters_default,
56
57
  ProviderManager: () => provider_default,
58
+ PublishEvent: () => publish_event_default,
57
59
  RegistrationManager: () => registration_default,
58
60
  RestClient: () => rest_client_default,
59
61
  RuntimeAction: () => runtime_action_default,
60
62
  RuntimeActionResponse: () => response_default,
61
- Validator: () => validator_default
63
+ ShippingCarrier: () => shipping_carrier_default,
64
+ ShippingCarrierMethod: () => method_default,
65
+ ShippingCarrierResponse: () => response_default3,
66
+ SignatureVerification: () => SignatureVerification,
67
+ Validator: () => validator_default,
68
+ WebhookAction: () => webhook_action_default,
69
+ WebhookActionOperation: () => WebhookActionOperation,
70
+ WebhookActionResponse: () => response_default2
62
71
  });
63
72
  module.exports = __toCommonJS(index_exports);
64
73
 
@@ -457,15 +466,34 @@ var _FileRepository = class _FileRepository {
457
466
  async list() {
458
467
  const filesLib = await this.getFiles();
459
468
  const results = [];
460
- const existingFiles = await filesLib.list(`${this.filepath}/`);
469
+ const existingFiles = await this.metadata();
461
470
  if (existingFiles.length) {
462
- for (const { name } of existingFiles) {
463
- const buffer = await filesLib.read(`${name}`);
464
- results.push(JSON.parse(buffer.toString()));
471
+ for (const file of existingFiles) {
472
+ const buffer = await filesLib.read(`${file.name}`);
473
+ const data = JSON.parse(buffer.toString());
474
+ results.push({
475
+ ...data,
476
+ createdAt: file.creationTime.toISOString(),
477
+ updatedAt: file.lastModified.toISOString()
478
+ });
465
479
  }
466
480
  }
467
481
  return results;
468
482
  }
483
+ /**
484
+ * Lists file metadata without reading file contents
485
+ * Provides a lightweight alternative to list() for performance-critical operations
486
+ * @param id - Optional ID of a specific file to get metadata for
487
+ * @returns Promise<FileMetadata | FileMetadata[]> Single file metadata if id provided, array of all files otherwise
488
+ */
489
+ async metadata(id) {
490
+ const filesLib = await this.getFiles();
491
+ if (id) {
492
+ const filepath = `${this.filepath}/${id}.json`;
493
+ return await filesLib.getProperties(filepath);
494
+ }
495
+ return await filesLib.list(`${this.filepath}/`);
496
+ }
469
497
  /**
470
498
  * Loads a specific file by ID
471
499
  * @param id - The ID of the file to load
@@ -477,7 +505,13 @@ var _FileRepository = class _FileRepository {
477
505
  const existingFile = await filesLib.list(filepath);
478
506
  if (existingFile.length) {
479
507
  const buffer = await filesLib.read(filepath);
480
- return JSON.parse(buffer.toString());
508
+ const data = JSON.parse(buffer.toString());
509
+ const fileProps = await filesLib.getProperties(filepath);
510
+ return {
511
+ ...data,
512
+ createdAt: fileProps.creationTime.toISOString(),
513
+ updatedAt: fileProps.lastModified.toISOString()
514
+ };
481
515
  }
482
516
  return {};
483
517
  }
@@ -485,9 +519,12 @@ var _FileRepository = class _FileRepository {
485
519
  * Saves a file record to the repository
486
520
  * @param payload - The data to save
487
521
  * @param id - Optional ID for the file (sanitized to alphanumeric + underscore, takes precedence over payload.id)
522
+ * @param overwrite - Optional flag to control file write behavior:
523
+ * - true: Replace file entirely with payload (no merge)
524
+ * - false (default): Merge payload with existing file content
488
525
  * @returns Promise<string | null> The filename on success, null on failure
489
526
  */
490
- async save(payload = {}, id) {
527
+ async save(payload = {}, id, overwrite = false) {
491
528
  try {
492
529
  const filesLib = await this.getFiles();
493
530
  let fileId;
@@ -501,23 +538,26 @@ var _FileRepository = class _FileRepository {
501
538
  const filepath = `${this.filepath}/${fileId}.json`;
502
539
  const existingFile = await filesLib.list(filepath);
503
540
  if (existingFile.length) {
504
- const buffer = await filesLib.read(filepath);
505
- const existingData = JSON.parse(buffer.toString());
506
- payload = {
507
- ...payload,
508
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
509
- };
510
- payload = { ...existingData, ...payload };
541
+ if (overwrite) {
542
+ console.log(`Overwriting existing file: ${filepath}`);
543
+ payload = {
544
+ id: fileId,
545
+ ...payload
546
+ };
547
+ } else {
548
+ const buffer = await filesLib.read(filepath);
549
+ const existingData = JSON.parse(buffer.toString());
550
+ payload = { ...existingData, ...payload };
551
+ }
511
552
  await filesLib.delete(filepath);
512
553
  } else {
513
554
  payload = {
514
- ...payload,
515
555
  id: fileId,
516
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
517
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
556
+ ...payload
518
557
  };
519
558
  }
520
- await filesLib.write(filepath, JSON.stringify(payload));
559
+ const { createdAt, updatedAt, ...payloadWithoutTimestamps } = payload;
560
+ await filesLib.write(filepath, JSON.stringify(payloadWithoutTimestamps));
521
561
  return fileId;
522
562
  } catch (error) {
523
563
  console.error("Error saving file:", error);
@@ -566,6 +606,418 @@ __name(_FileRepository, "FileRepository");
566
606
  var FileRepository = _FileRepository;
567
607
  var file_repository_default = FileRepository;
568
608
 
609
+ // src/framework/publish-event/index.ts
610
+ var import_aio_sdk5 = require("@adobe/aio-sdk");
611
+ var import_cloudevents = require("cloudevents");
612
+ var import_uuid = require("uuid");
613
+
614
+ // src/framework/custom-logger/index.ts
615
+ var _CustomLogger = class _CustomLogger {
616
+ /**
617
+ * @param logger - External logger instance (can be null)
618
+ */
619
+ constructor(logger = null) {
620
+ this.logger = logger;
621
+ }
622
+ /**
623
+ * Log debug message if logger is available
624
+ * @param message - Debug message to log
625
+ */
626
+ debug(message) {
627
+ if (this.logger && typeof this.logger.debug === "function") {
628
+ this.logger.debug(message);
629
+ }
630
+ }
631
+ /**
632
+ * Log info message if logger is available
633
+ * @param message - Info message to log
634
+ */
635
+ info(message) {
636
+ if (this.logger && typeof this.logger.info === "function") {
637
+ this.logger.info(message);
638
+ }
639
+ }
640
+ /**
641
+ * Log error message if logger is available
642
+ * @param message - Error message to log
643
+ */
644
+ error(message) {
645
+ if (this.logger && typeof this.logger.error === "function") {
646
+ this.logger.error(message);
647
+ }
648
+ }
649
+ /**
650
+ * Get the underlying logger instance
651
+ * @returns the logger instance or null
652
+ */
653
+ getLogger() {
654
+ return this.logger;
655
+ }
656
+ };
657
+ __name(_CustomLogger, "CustomLogger");
658
+ var CustomLogger = _CustomLogger;
659
+ var custom_logger_default = CustomLogger;
660
+
661
+ // src/framework/publish-event/index.ts
662
+ var _PublishEvent = class _PublishEvent {
663
+ /**
664
+ * Creates a new PublishEvent instance
665
+ *
666
+ * @param imsOrgId - Adobe IMS Organization ID
667
+ * @param apiKey - Adobe API Key (Client ID)
668
+ * @param accessToken - Adobe Access Token
669
+ * @param logger - Optional logger instance
670
+ */
671
+ constructor(imsOrgId, apiKey, accessToken, logger = null) {
672
+ if (!imsOrgId?.trim()) {
673
+ throw new Error("imsOrgId is required and cannot be empty");
674
+ }
675
+ if (!apiKey?.trim()) {
676
+ throw new Error("apiKey is required and cannot be empty");
677
+ }
678
+ if (!accessToken?.trim()) {
679
+ throw new Error("accessToken is required and cannot be empty");
680
+ }
681
+ this.imsOrgId = imsOrgId;
682
+ this.apiKey = apiKey;
683
+ this.accessToken = accessToken;
684
+ this.customLogger = new custom_logger_default(logger);
685
+ this.customLogger.debug("PublishEvent initialized with valid configuration");
686
+ }
687
+ /**
688
+ * Publishes a CloudEvent to Adobe I/O Events
689
+ *
690
+ * @param providerId - The Adobe I/O Events provider ID
691
+ * @param eventCode - The event type identifier (e.g., 'commerce.order.created')
692
+ * @param payload - The event payload data
693
+ * @param subject - Optional subject for the event
694
+ * @returns Promise<PublishEventResult> - The publish result
695
+ *
696
+ * @throws Error when providerId or eventCode is invalid or publishing fails
697
+ */
698
+ async execute(providerId, eventCode, payload, subject) {
699
+ try {
700
+ if (!providerId?.trim()) {
701
+ throw new Error("providerId is required and cannot be empty");
702
+ }
703
+ if (!eventCode?.trim()) {
704
+ throw new Error("eventCode is required and cannot be empty");
705
+ }
706
+ if (payload === null || payload === void 0) {
707
+ throw new Error("payload is required");
708
+ }
709
+ this.customLogger.info(`Publishing event to provider: ${providerId}`);
710
+ const eventId = (0, import_uuid.v4)();
711
+ const cloudEvent = new import_cloudevents.CloudEvent({
712
+ id: eventId,
713
+ source: `urn:uuid:${providerId}`,
714
+ datacontenttype: "application/json",
715
+ type: eventCode,
716
+ data: payload,
717
+ ...subject && { subject }
718
+ });
719
+ this.customLogger.debug(`Constructed CloudEvent with ID: ${eventId}`);
720
+ const eventsClient = await import_aio_sdk5.Events.init(this.imsOrgId, this.apiKey, this.accessToken);
721
+ this.customLogger.debug("Adobe I/O Events client initialized successfully");
722
+ await eventsClient.publishEvent(cloudEvent);
723
+ const publishedAt = (/* @__PURE__ */ new Date()).toISOString();
724
+ this.customLogger.info(`Event published successfully with ID: ${eventId}`);
725
+ return {
726
+ eventId,
727
+ status: "published",
728
+ publishedAt
729
+ };
730
+ } catch (error) {
731
+ this.customLogger.error(`Failed to publish event: ${error.message}`);
732
+ return {
733
+ eventId: (0, import_uuid.v4)(),
734
+ // Generate ID for tracking even failed events
735
+ status: "failed",
736
+ publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
737
+ error: error.message
738
+ };
739
+ }
740
+ }
741
+ };
742
+ __name(_PublishEvent, "PublishEvent");
743
+ var PublishEvent = _PublishEvent;
744
+ var publish_event_default = PublishEvent;
745
+
746
+ // src/framework/webhook-action/response/types.ts
747
+ var WebhookActionOperation = /* @__PURE__ */ ((WebhookActionOperation2) => {
748
+ WebhookActionOperation2["SUCCESS"] = "success";
749
+ WebhookActionOperation2["EXCEPTION"] = "exception";
750
+ WebhookActionOperation2["ADD"] = "add";
751
+ WebhookActionOperation2["REPLACE"] = "replace";
752
+ WebhookActionOperation2["REMOVE"] = "remove";
753
+ return WebhookActionOperation2;
754
+ })(WebhookActionOperation || {});
755
+
756
+ // src/framework/webhook-action/response/index.ts
757
+ var _WebhookActionResponse = class _WebhookActionResponse {
758
+ /**
759
+ * Creates a success response indicating the webhook was processed successfully.
760
+ *
761
+ * Use this method when the webhook has been processed without errors and
762
+ * no modifications to the payload are needed.
763
+ *
764
+ * @returns A success response object
765
+ *
766
+ * @example
767
+ * ```typescript
768
+ * const handler = WebhookAction.execute('process-order', [], [], async (params) => {
769
+ * // Process the order...
770
+ * await processOrder(params.order);
771
+ *
772
+ * // Return success
773
+ * return {
774
+ * statusCode: 200,
775
+ * body: WebhookActionResponse.success()
776
+ * };
777
+ * });
778
+ * ```
779
+ */
780
+ static success() {
781
+ return {
782
+ op: "success" /* SUCCESS */
783
+ };
784
+ }
785
+ /**
786
+ * Creates an exception response to report an error during webhook processing.
787
+ *
788
+ * Use this method to notify Adobe Commerce that an error occurred while
789
+ * processing the webhook. This helps with debugging and error tracking.
790
+ *
791
+ * @param message - Optional error message describing what went wrong
792
+ * @param exceptionClass - Optional exception class name for categorization (e.g., 'Magento\\Framework\\Exception\\LocalizedException')
793
+ * @returns An exception response object
794
+ *
795
+ * @example
796
+ * ```typescript
797
+ * const handler = WebhookAction.execute('validate-product', [], [], async (params) => {
798
+ * const product = await findProduct(params.sku);
799
+ *
800
+ * if (!product) {
801
+ * return {
802
+ * statusCode: 404,
803
+ * body: WebhookActionResponse.exception(
804
+ * `Product with SKU ${params.sku} not found`,
805
+ * 'Magento\\Framework\\Exception\\NoSuchEntityException'
806
+ * )
807
+ * };
808
+ * }
809
+ *
810
+ * return { statusCode: 200, body: WebhookActionResponse.success() };
811
+ * });
812
+ * ```
813
+ */
814
+ static exception(message, exceptionClass) {
815
+ const response = {
816
+ op: "exception" /* EXCEPTION */
817
+ };
818
+ if (message !== void 0) {
819
+ response.message = message;
820
+ }
821
+ if (exceptionClass !== void 0) {
822
+ response.class = exceptionClass;
823
+ }
824
+ return response;
825
+ }
826
+ /**
827
+ * Creates a response to add new data to the webhook payload.
828
+ *
829
+ * Use this method to inject additional data into the webhook payload that
830
+ * will be processed by Adobe Commerce. The data is added at the specified
831
+ * path using dot notation.
832
+ *
833
+ * @param path - Dot-notation path where the value should be added (e.g., 'order.items', 'customer.addresses')
834
+ * @param value - The value to add at the specified path
835
+ * @param instance - Optional instance identifier for tracking or reference purposes
836
+ * @returns An add response object
837
+ *
838
+ * @example
839
+ * ```typescript
840
+ * const handler = WebhookAction.execute('enrich-order', [], [], async (params) => {
841
+ * // Add loyalty points to the order
842
+ * return {
843
+ * statusCode: 200,
844
+ * body: WebhookActionResponse.add(
845
+ * 'order.loyalty',
846
+ * { points: 150, tier: 'gold' },
847
+ * params.order.id
848
+ * )
849
+ * };
850
+ * });
851
+ * ```
852
+ */
853
+ static add(path, value, instance) {
854
+ const response = {
855
+ op: "add" /* ADD */,
856
+ path,
857
+ value
858
+ };
859
+ if (instance !== void 0) {
860
+ response.instance = instance;
861
+ }
862
+ return response;
863
+ }
864
+ /**
865
+ * Creates a response to replace existing data in the webhook payload.
866
+ *
867
+ * Use this method to modify existing fields in the webhook payload.
868
+ * The existing value at the specified path will be replaced with the new value.
869
+ *
870
+ * @param path - Dot-notation path to the field that should be replaced (e.g., 'product.price', 'order.status')
871
+ * @param value - The new value to replace the existing value
872
+ * @param instance - Optional instance identifier for tracking or reference purposes
873
+ * @returns A replace response object
874
+ *
875
+ * @example
876
+ * ```typescript
877
+ * const handler = WebhookAction.execute('adjust-price', [], [], async (params) => {
878
+ * // Apply dynamic pricing
879
+ * const newPrice = await calculateDiscountedPrice(params.product.price);
880
+ *
881
+ * return {
882
+ * statusCode: 200,
883
+ * body: WebhookActionResponse.replace(
884
+ * 'product.price',
885
+ * newPrice,
886
+ * params.product.id
887
+ * )
888
+ * };
889
+ * });
890
+ * ```
891
+ */
892
+ static replace(path, value, instance) {
893
+ const response = {
894
+ op: "replace" /* REPLACE */,
895
+ path,
896
+ value
897
+ };
898
+ if (instance !== void 0) {
899
+ response.instance = instance;
900
+ }
901
+ return response;
902
+ }
903
+ /**
904
+ * Creates a response to remove data from the webhook payload.
905
+ *
906
+ * Use this method to remove fields from the webhook payload before it's
907
+ * processed by Adobe Commerce. This is useful for filtering sensitive data
908
+ * or removing unnecessary information.
909
+ *
910
+ * @param path - Dot-notation path to the field that should be removed (e.g., 'items.0', 'customer.internal_notes')
911
+ * @returns A remove response object
912
+ *
913
+ * @example
914
+ * ```typescript
915
+ * const handler = WebhookAction.execute('sanitize-customer', [], [], async (params) => {
916
+ * // Remove internal notes before processing
917
+ * return {
918
+ * statusCode: 200,
919
+ * body: WebhookActionResponse.remove('customer.internal_notes')
920
+ * };
921
+ * });
922
+ * ```
923
+ *
924
+ * @example
925
+ * ```typescript
926
+ * // Remove an item from an array
927
+ * return {
928
+ * statusCode: 200,
929
+ * body: WebhookActionResponse.remove('order.items.2')
930
+ * };
931
+ * ```
932
+ */
933
+ static remove(path) {
934
+ return {
935
+ op: "remove" /* REMOVE */,
936
+ path
937
+ };
938
+ }
939
+ };
940
+ __name(_WebhookActionResponse, "WebhookActionResponse");
941
+ var WebhookActionResponse = _WebhookActionResponse;
942
+ var response_default2 = WebhookActionResponse;
943
+
944
+ // src/framework/webhook-action/types.ts
945
+ var SignatureVerification = /* @__PURE__ */ ((SignatureVerification2) => {
946
+ SignatureVerification2["ENABLED"] = "enabled";
947
+ SignatureVerification2["DISABLED"] = "disabled";
948
+ return SignatureVerification2;
949
+ })(SignatureVerification || {});
950
+
951
+ // src/framework/webhook-action/index.ts
952
+ var import_crypto = __toESM(require("crypto"));
953
+ var _WebhookAction = class _WebhookAction {
954
+ /**
955
+ * Execute a webhook action with validation and response handling.
956
+ *
957
+ * @param name - Name of the webhook action
958
+ * @param requiredParams - Required parameters in the webhook payload
959
+ * @param requiredHeaders - Required headers (e.g., signature headers)
960
+ * @param signatureVerification - Enable/disable signature verification
961
+ * @param action - Webhook action function returning WebhookActionResponse
962
+ * @returns Function that handles the webhook HTTP request
963
+ */
964
+ static execute(name = "webhook", requiredParams = [], requiredHeaders = [], signatureVerification = "disabled" /* DISABLED */, action = async () => response_default2.success()) {
965
+ const httpMethods = ["POST" /* POST */];
966
+ const verifySignature = /* @__PURE__ */ __name(async (params) => {
967
+ const signature = params.__ow_headers["x-adobe-commerce-webhook-signature"] || "";
968
+ if (!signature) {
969
+ return "Header `x-adobe-commerce-webhook-signature` not found. Make sure Webhooks signature is enabled in the Commerce instance.";
970
+ }
971
+ const body = params.__ow_body;
972
+ if (!body) {
973
+ return "Request body not found. Make sure the action is configured with `raw-http: true`.";
974
+ }
975
+ let publicKey = params.PUBLIC_KEY;
976
+ if (!publicKey && params.PUBLIC_KEY_BASE64) {
977
+ publicKey = atob(params.PUBLIC_KEY_BASE64);
978
+ }
979
+ if (!publicKey) {
980
+ return "Public key not found. Make sure the action is configured with the input `PUBLIC_KEY` or `PUBLIC_KEY_BASE64` and it is defined in .env file.";
981
+ }
982
+ try {
983
+ const verifier = import_crypto.default.createVerify("SHA256");
984
+ verifier.update(body);
985
+ const isSignatureValid = verifier.verify(publicKey, signature, "base64");
986
+ if (!isSignatureValid) {
987
+ return "The signature is invalid.";
988
+ }
989
+ } catch (error) {
990
+ return "The signature is invalid.";
991
+ }
992
+ return null;
993
+ }, "verifySignature");
994
+ const callback = /* @__PURE__ */ __name(async (params, ctx) => {
995
+ if (signatureVerification === "enabled" /* ENABLED */) {
996
+ const verificationErrorMessage = await verifySignature(params);
997
+ if (verificationErrorMessage) {
998
+ const verificationErrorResponse = response_default2.exception(verificationErrorMessage);
999
+ return response_default.success(JSON.stringify(verificationErrorResponse));
1000
+ }
1001
+ params = {
1002
+ ...params,
1003
+ ...JSON.parse(atob(params.__ow_body))
1004
+ };
1005
+ }
1006
+ const errorMessage = validator_default.checkMissingRequestInputs(params, requiredParams, requiredHeaders) ?? "";
1007
+ if (errorMessage) {
1008
+ const errorMessageResponse = response_default2.exception(errorMessage);
1009
+ return response_default.success(JSON.stringify(errorMessageResponse));
1010
+ }
1011
+ const response = await action(params, ctx);
1012
+ return response_default.success(JSON.stringify(response));
1013
+ }, "callback");
1014
+ return runtime_action_default.execute(name, httpMethods, [], [], callback);
1015
+ }
1016
+ };
1017
+ __name(_WebhookAction, "WebhookAction");
1018
+ var WebhookAction = _WebhookAction;
1019
+ var webhook_action_default = WebhookAction;
1020
+
569
1021
  // src/integration/bearer-token/index.ts
570
1022
  var _BearerToken = class _BearerToken {
571
1023
  /**
@@ -883,7 +1335,7 @@ var RestClient = _RestClient;
883
1335
  var rest_client_default = RestClient;
884
1336
 
885
1337
  // src/integration/onboard-events/index.ts
886
- var import_aio_sdk5 = require("@adobe/aio-sdk");
1338
+ var import_aio_sdk6 = require("@adobe/aio-sdk");
887
1339
 
888
1340
  // src/io-events/types.ts
889
1341
  var IoEventsGlobals = {
@@ -3393,7 +3845,7 @@ var RegistrationManager = _RegistrationManager;
3393
3845
  var registration_default = RegistrationManager;
3394
3846
 
3395
3847
  // src/integration/onboard-events/create-providers/index.ts
3396
- var import_crypto = require("crypto");
3848
+ var import_crypto2 = require("crypto");
3397
3849
  var _CreateProviders = class _CreateProviders {
3398
3850
  /**
3399
3851
  * Creates a new CreateProviders instance
@@ -3589,7 +4041,7 @@ var _CreateProviders = class _CreateProviders {
3589
4041
  }
3590
4042
  if (this.isCommerceProvider(providerData)) {
3591
4043
  input.provider_metadata = "dx_commerce_events";
3592
- input.instance_id = (0, import_crypto.randomUUID)();
4044
+ input.instance_id = (0, import_crypto2.randomUUID)();
3593
4045
  }
3594
4046
  return input;
3595
4047
  }
@@ -4198,7 +4650,7 @@ var _OnboardEvents = class _OnboardEvents {
4198
4650
  throw new Error("Access token is required");
4199
4651
  }
4200
4652
  const loggerName = projectName.toLowerCase().replace(/[^a-z0-9\s-_]/g, "").replace(/\s+/g, "-").replace(/_{2,}/g, "_").replace(/-{2,}/g, "-").trim().concat("-onboard-events");
4201
- this.logger = import_aio_sdk5.Core.Logger(loggerName, { level: "debug" });
4653
+ this.logger = import_aio_sdk6.Core.Logger(loggerName, { level: "debug" });
4202
4654
  this.createProviders = new create_providers_default(
4203
4655
  consumerId,
4204
4656
  projectId,
@@ -4394,8 +4846,8 @@ var OnboardEvents = _OnboardEvents;
4394
4846
  var onboard_events_default = OnboardEvents;
4395
4847
 
4396
4848
  // src/integration/infinite-loop-breaker/index.ts
4397
- var import_aio_sdk6 = require("@adobe/aio-sdk");
4398
- var import_crypto2 = __toESM(require("crypto"));
4849
+ var import_aio_sdk7 = require("@adobe/aio-sdk");
4850
+ var import_crypto3 = __toESM(require("crypto"));
4399
4851
  var _InfiniteLoopBreaker = class _InfiniteLoopBreaker {
4400
4852
  // seconds
4401
4853
  /**
@@ -4412,7 +4864,7 @@ var _InfiniteLoopBreaker = class _InfiniteLoopBreaker {
4412
4864
  event
4413
4865
  }) {
4414
4866
  const logLevel = process.env.LOG_LEVEL || "info";
4415
- const logger = import_aio_sdk6.Core.Logger("infiniteLoopBreaker", { level: logLevel });
4867
+ const logger = import_aio_sdk7.Core.Logger("infiniteLoopBreaker", { level: logLevel });
4416
4868
  logger.debug(`Checking for potential infinite loop for event: ${event}`);
4417
4869
  if (!eventTypes.includes(event)) {
4418
4870
  logger.debug(`Event type ${event} is not in the infinite loop event types list`);
@@ -4420,7 +4872,7 @@ var _InfiniteLoopBreaker = class _InfiniteLoopBreaker {
4420
4872
  }
4421
4873
  const key = typeof keyFn === "function" ? keyFn() : keyFn;
4422
4874
  const data = typeof fingerprintFn === "function" ? fingerprintFn() : fingerprintFn;
4423
- const state = await import_aio_sdk6.State.init();
4875
+ const state = await import_aio_sdk7.State.init();
4424
4876
  const persistedFingerPrint = await state.get(key);
4425
4877
  if (!persistedFingerPrint) {
4426
4878
  logger.debug(`No persisted fingerprint found for key ${key}`);
@@ -4441,7 +4893,7 @@ var _InfiniteLoopBreaker = class _InfiniteLoopBreaker {
4441
4893
  static async storeFingerPrint(keyFn, fingerprintFn, ttl) {
4442
4894
  const key = typeof keyFn === "function" ? keyFn() : keyFn;
4443
4895
  const data = typeof fingerprintFn === "function" ? fingerprintFn() : fingerprintFn;
4444
- const state = await import_aio_sdk6.State.init();
4896
+ const state = await import_aio_sdk7.State.init();
4445
4897
  await state.put(key, _InfiniteLoopBreaker.fingerPrint(data), {
4446
4898
  ttl: ttl !== void 0 ? ttl : _InfiniteLoopBreaker.DEFAULT_INFINITE_LOOP_BREAKER_TTL
4447
4899
  });
@@ -4475,7 +4927,7 @@ var _InfiniteLoopBreaker = class _InfiniteLoopBreaker {
4475
4927
  * @returns The fingerprint
4476
4928
  */
4477
4929
  static fingerPrint(data) {
4478
- const hash = import_crypto2.default.createHash(_InfiniteLoopBreaker.FINGERPRINT_ALGORITHM);
4930
+ const hash = import_crypto3.default.createHash(_InfiniteLoopBreaker.FINGERPRINT_ALGORITHM);
4479
4931
  hash.update(JSON.stringify(data));
4480
4932
  return hash.digest(_InfiniteLoopBreaker.FINGERPRINT_ENCODING);
4481
4933
  }
@@ -4534,7 +4986,7 @@ var AdobeAuth = _AdobeAuth;
4534
4986
  var adobe_auth_default = AdobeAuth;
4535
4987
 
4536
4988
  // src/commerce/adobe-commerce-client/index.ts
4537
- var import_aio_sdk7 = require("@adobe/aio-sdk");
4989
+ var import_aio_sdk8 = require("@adobe/aio-sdk");
4538
4990
  var import_got = __toESM(require("got"));
4539
4991
  var _AdobeCommerceClient = class _AdobeCommerceClient {
4540
4992
  /**
@@ -4549,7 +5001,7 @@ var _AdobeCommerceClient = class _AdobeCommerceClient {
4549
5001
  this.baseUrl = baseUrl;
4550
5002
  this.connection = connection;
4551
5003
  if (logger === null) {
4552
- logger = import_aio_sdk7.Core.Logger("adobe-commerce-client", {
5004
+ logger = import_aio_sdk8.Core.Logger("adobe-commerce-client", {
4553
5005
  level: "debug"
4554
5006
  });
4555
5007
  }
@@ -4676,10 +5128,10 @@ var AdobeCommerceClient = _AdobeCommerceClient;
4676
5128
  var adobe_commerce_client_default = AdobeCommerceClient;
4677
5129
 
4678
5130
  // src/commerce/adobe-commerce-client/basic-auth-connection/index.ts
4679
- var import_aio_sdk9 = require("@adobe/aio-sdk");
5131
+ var import_aio_sdk10 = require("@adobe/aio-sdk");
4680
5132
 
4681
5133
  // src/commerce/adobe-commerce-client/basic-auth-connection/generate-basic-auth-token/index.ts
4682
- var import_aio_sdk8 = require("@adobe/aio-sdk");
5134
+ var import_aio_sdk9 = require("@adobe/aio-sdk");
4683
5135
  var _GenerateBasicAuthToken = class _GenerateBasicAuthToken {
4684
5136
  /**
4685
5137
  * @param baseUrl
@@ -4693,7 +5145,7 @@ var _GenerateBasicAuthToken = class _GenerateBasicAuthToken {
4693
5145
  this.password = password;
4694
5146
  this.key = "adobe_commerce_basic_auth_token";
4695
5147
  if (logger === null) {
4696
- logger = import_aio_sdk8.Core.Logger("adobe-commerce-client", {
5148
+ logger = import_aio_sdk9.Core.Logger("adobe-commerce-client", {
4697
5149
  level: "debug"
4698
5150
  });
4699
5151
  }
@@ -4725,7 +5177,7 @@ var _GenerateBasicAuthToken = class _GenerateBasicAuthToken {
4725
5177
  * @return TokenResult | null
4726
5178
  */
4727
5179
  async getCommerceToken() {
4728
- const endpoint = this.createEndpoint("rest/V1/integration/admin/token");
5180
+ const endpoint = this.createTokenEndpoint();
4729
5181
  this.logger.debug(`Endpoint: ${endpoint}`);
4730
5182
  try {
4731
5183
  const restClient = new rest_client_default();
@@ -4771,6 +5223,19 @@ var _GenerateBasicAuthToken = class _GenerateBasicAuthToken {
4771
5223
  return null;
4772
5224
  }
4773
5225
  }
5226
+ /**
5227
+ * Create the Adobe Commerce integration admin token endpoint.
5228
+ * Handles cases where baseUrl may or may not already include /rest.
5229
+ * @return string
5230
+ */
5231
+ createTokenEndpoint() {
5232
+ const normalizedBaseUrl = this.baseUrl.replace(/\/+$/, "");
5233
+ if (normalizedBaseUrl.endsWith("/rest")) {
5234
+ return `${normalizedBaseUrl}/V1/integration/admin/token`;
5235
+ } else {
5236
+ return `${normalizedBaseUrl}/rest/V1/integration/admin/token`;
5237
+ }
5238
+ }
4774
5239
  /**
4775
5240
  * @param endpoint
4776
5241
  * @return string
@@ -4821,7 +5286,7 @@ var _GenerateBasicAuthToken = class _GenerateBasicAuthToken {
4821
5286
  async getState() {
4822
5287
  if (this.state === void 0) {
4823
5288
  try {
4824
- this.state = await import_aio_sdk8.State.init();
5289
+ this.state = await import_aio_sdk9.State.init();
4825
5290
  } catch (error) {
4826
5291
  this.logger.debug("State API initialization failed, running without caching");
4827
5292
  this.state = null;
@@ -4847,7 +5312,7 @@ var _BasicAuthConnection = class _BasicAuthConnection {
4847
5312
  this.username = username;
4848
5313
  this.password = password;
4849
5314
  if (logger === null) {
4850
- logger = import_aio_sdk9.Core.Logger("adobe-commerce-client", {
5315
+ logger = import_aio_sdk10.Core.Logger("adobe-commerce-client", {
4851
5316
  level: "debug"
4852
5317
  });
4853
5318
  }
@@ -4877,9 +5342,9 @@ var BasicAuthConnection = _BasicAuthConnection;
4877
5342
  var basic_auth_connection_default = BasicAuthConnection;
4878
5343
 
4879
5344
  // src/commerce/adobe-commerce-client/oauth1a-connection/index.ts
4880
- var import_aio_sdk10 = require("@adobe/aio-sdk");
5345
+ var import_aio_sdk11 = require("@adobe/aio-sdk");
4881
5346
  var import_oauth_1 = __toESM(require("oauth-1.0a"));
4882
- var crypto2 = __toESM(require("crypto"));
5347
+ var crypto3 = __toESM(require("crypto"));
4883
5348
  var _Oauth1aConnection = class _Oauth1aConnection {
4884
5349
  /**
4885
5350
  * @param consumerKey
@@ -4894,7 +5359,7 @@ var _Oauth1aConnection = class _Oauth1aConnection {
4894
5359
  this.accessToken = accessToken;
4895
5360
  this.accessTokenSecret = accessTokenSecret;
4896
5361
  if (logger === null) {
4897
- logger = import_aio_sdk10.Core.Logger("adobe-commerce-client", {
5362
+ logger = import_aio_sdk11.Core.Logger("adobe-commerce-client", {
4898
5363
  level: "debug"
4899
5364
  });
4900
5365
  }
@@ -4928,7 +5393,7 @@ var _Oauth1aConnection = class _Oauth1aConnection {
4928
5393
  secret: this.consumerSecret
4929
5394
  },
4930
5395
  signature_method: "HMAC-SHA256",
4931
- hash_function: /* @__PURE__ */ __name((baseString, key) => crypto2.createHmac("sha256", key).update(baseString).digest("base64"), "hash_function")
5396
+ hash_function: /* @__PURE__ */ __name((baseString, key) => crypto3.createHmac("sha256", key).update(baseString).digest("base64"), "hash_function")
4932
5397
  });
4933
5398
  const oauthToken = {
4934
5399
  key: this.accessToken,
@@ -4941,8 +5406,161 @@ __name(_Oauth1aConnection, "Oauth1aConnection");
4941
5406
  var Oauth1aConnection = _Oauth1aConnection;
4942
5407
  var oauth1a_connection_default = Oauth1aConnection;
4943
5408
 
5409
+ // src/commerce/adobe-commerce-client/ims-connection/generate-ims-token/index.ts
5410
+ var import_aio_sdk12 = require("@adobe/aio-sdk");
5411
+ var _GenerateImsToken = class _GenerateImsToken {
5412
+ /**
5413
+ * @param clientId
5414
+ * @param clientSecret
5415
+ * @param technicalAccountId
5416
+ * @param technicalAccountEmail
5417
+ * @param imsOrgId
5418
+ * @param scopes
5419
+ * @param logger
5420
+ */
5421
+ constructor(clientId, clientSecret, technicalAccountId, technicalAccountEmail, imsOrgId, scopes, logger = null) {
5422
+ this.key = "adobe_ims_auth_token";
5423
+ this.tokenContext = "adobe-commerce-client";
5424
+ this.clientId = clientId;
5425
+ this.clientSecret = clientSecret;
5426
+ this.technicalAccountId = technicalAccountId;
5427
+ this.technicalAccountEmail = technicalAccountEmail;
5428
+ this.imsOrgId = imsOrgId;
5429
+ this.scopes = scopes;
5430
+ this.customLogger = new custom_logger_default(logger);
5431
+ }
5432
+ /**
5433
+ * @return string | null
5434
+ */
5435
+ async execute() {
5436
+ try {
5437
+ this.customLogger.info("Starting IMS token generation/retrieval process");
5438
+ const currentValue = await this.getValue();
5439
+ if (currentValue !== null) {
5440
+ this.customLogger.info("Found cached IMS token, returning cached value");
5441
+ return currentValue;
5442
+ }
5443
+ this.customLogger.info("No cached token found, generating new IMS token");
5444
+ let result = {
5445
+ token: null,
5446
+ expire_in: 86399
5447
+ // Default fallback, will be overridden by actual token expiry
5448
+ };
5449
+ const response = await this.getImsToken();
5450
+ if (response !== null) {
5451
+ result = response;
5452
+ }
5453
+ if (result.token !== null) {
5454
+ this.customLogger.info(`Generated new IMS token, caching for ${result.expire_in} seconds`);
5455
+ await this.setValue(result);
5456
+ }
5457
+ return result.token;
5458
+ } catch (error) {
5459
+ this.customLogger.error(`Failed to execute IMS token generation: ${error.message}`);
5460
+ return null;
5461
+ }
5462
+ }
5463
+ /**
5464
+ * @return ImsTokenResult | null
5465
+ */
5466
+ async getImsToken() {
5467
+ try {
5468
+ this.customLogger.debug(`Calling AdobeAuth.getToken with context: ${this.tokenContext}`);
5469
+ const token = await adobe_auth_default.getToken(
5470
+ this.clientId,
5471
+ this.clientSecret,
5472
+ this.technicalAccountId,
5473
+ this.technicalAccountEmail,
5474
+ this.imsOrgId,
5475
+ this.scopes,
5476
+ this.tokenContext
5477
+ );
5478
+ if (token !== null && token !== void 0) {
5479
+ this.customLogger.debug("Received token from AdobeAuth, parsing with BearerToken.info");
5480
+ const tokenInfo = bearer_token_default.info(token);
5481
+ if (!tokenInfo.isValid) {
5482
+ this.customLogger.error("Received invalid or expired token from IMS");
5483
+ return null;
5484
+ }
5485
+ const expireInSeconds = tokenInfo.timeUntilExpiry ? Math.floor(tokenInfo.timeUntilExpiry / 1e3) : 86399;
5486
+ this.customLogger.debug(`Token expires in ${expireInSeconds} seconds`);
5487
+ return {
5488
+ token,
5489
+ expire_in: expireInSeconds
5490
+ };
5491
+ }
5492
+ this.customLogger.error("Received null or undefined token from IMS");
5493
+ return null;
5494
+ } catch (error) {
5495
+ this.customLogger.error(`Failed to get IMS token: ${error.message}`);
5496
+ return null;
5497
+ }
5498
+ }
5499
+ /**
5500
+ * @param result
5501
+ * @return boolean
5502
+ */
5503
+ async setValue(result) {
5504
+ try {
5505
+ const state = await this.getState();
5506
+ if (state === null) {
5507
+ this.customLogger.info("State API not available, skipping token caching");
5508
+ return true;
5509
+ }
5510
+ const ttlWithBuffer = Math.max(result.expire_in - 300, 60);
5511
+ this.customLogger.debug(
5512
+ `Caching IMS token with TTL: ${ttlWithBuffer} seconds (original: ${result.expire_in})`
5513
+ );
5514
+ await state.put(this.key, result.token, { ttl: ttlWithBuffer });
5515
+ return true;
5516
+ } catch (error) {
5517
+ this.customLogger.error(`Failed to cache IMS token: ${error.message}`);
5518
+ return true;
5519
+ }
5520
+ }
5521
+ /**
5522
+ * @return string | null
5523
+ */
5524
+ async getValue() {
5525
+ try {
5526
+ this.customLogger.debug("Checking for cached IMS token");
5527
+ const state = await this.getState();
5528
+ if (state === null) {
5529
+ this.customLogger.debug("State API not available, cannot retrieve cached token");
5530
+ return null;
5531
+ }
5532
+ const value = await state.get(this.key);
5533
+ if (value !== void 0 && value.value) {
5534
+ this.customLogger.debug("Found cached IMS token");
5535
+ return value.value;
5536
+ }
5537
+ this.customLogger.debug("No cached IMS token found");
5538
+ } catch (error) {
5539
+ this.customLogger.error(`Failed to retrieve cached IMS token: ${error.message}`);
5540
+ }
5541
+ return null;
5542
+ }
5543
+ /**
5544
+ * @return any
5545
+ */
5546
+ async getState() {
5547
+ if (this.state === void 0) {
5548
+ try {
5549
+ this.customLogger.debug("Initializing State API for token caching");
5550
+ this.state = await import_aio_sdk12.State.init();
5551
+ } catch (error) {
5552
+ this.customLogger.error(`Failed to initialize State API: ${error.message}`);
5553
+ this.state = null;
5554
+ }
5555
+ }
5556
+ return this.state;
5557
+ }
5558
+ };
5559
+ __name(_GenerateImsToken, "GenerateImsToken");
5560
+ var GenerateImsToken = _GenerateImsToken;
5561
+ var generate_ims_token_default = GenerateImsToken;
5562
+
4944
5563
  // src/commerce/adobe-commerce-client/ims-connection/index.ts
4945
- var import_aio_sdk11 = require("@adobe/aio-sdk");
4946
5564
  var _ImsConnection = class _ImsConnection {
4947
5565
  /**
4948
5566
  * @param clientId
@@ -4952,38 +5570,35 @@ var _ImsConnection = class _ImsConnection {
4952
5570
  * @param imsOrgId
4953
5571
  * @param scopes
4954
5572
  * @param logger
4955
- * @param currentContext
4956
5573
  */
4957
- constructor(clientId, clientSecret, technicalAccountId, technicalAccountEmail, imsOrgId, scopes, logger = null, currentContext = "adobe-commerce-client") {
5574
+ constructor(clientId, clientSecret, technicalAccountId, technicalAccountEmail, imsOrgId, scopes, logger = null) {
4958
5575
  this.clientId = clientId;
4959
5576
  this.clientSecret = clientSecret;
4960
5577
  this.technicalAccountId = technicalAccountId;
4961
5578
  this.technicalAccountEmail = technicalAccountEmail;
4962
5579
  this.imsOrgId = imsOrgId;
4963
5580
  this.scopes = scopes;
4964
- this.currentContext = currentContext;
4965
- if (logger === null) {
4966
- logger = import_aio_sdk11.Core.Logger(currentContext, {
4967
- level: "debug"
4968
- });
4969
- }
4970
- this.logger = logger;
5581
+ this.customLogger = new custom_logger_default(logger);
4971
5582
  }
4972
5583
  /**
4973
5584
  * @param commerceGot
4974
5585
  */
4975
5586
  async extend(commerceGot) {
4976
- this.logger.debug("Using Commerce client with IMS authentication");
4977
- const token = await adobe_auth_default.getToken(
5587
+ this.customLogger.info("Using Commerce client with IMS authentication");
5588
+ const tokenGenerator = new generate_ims_token_default(
4978
5589
  this.clientId,
4979
5590
  this.clientSecret,
4980
5591
  this.technicalAccountId,
4981
5592
  this.technicalAccountEmail,
4982
5593
  this.imsOrgId,
4983
5594
  this.scopes,
4984
- this.currentContext
5595
+ this.customLogger.getLogger()
4985
5596
  );
4986
- this.logger.debug(`IMS token being extended to header: ${token}`);
5597
+ const token = await tokenGenerator.execute();
5598
+ if (token === null) {
5599
+ throw new Error("Failed to generate or retrieve IMS token");
5600
+ }
5601
+ this.customLogger.info(`IMS token being extended to header: ${token.substring(0, 10)}...`);
4987
5602
  return commerceGot.extend({
4988
5603
  headers: {
4989
5604
  Authorization: `Bearer ${token}`
@@ -4994,8 +5609,552 @@ var _ImsConnection = class _ImsConnection {
4994
5609
  __name(_ImsConnection, "ImsConnection");
4995
5610
  var ImsConnection = _ImsConnection;
4996
5611
  var ims_connection_default = ImsConnection;
5612
+
5613
+ // src/commerce/shipping-carrier/method/index.ts
5614
+ var _ShippingCarrierMethod = class _ShippingCarrierMethod {
5615
+ constructor(carrierCode, method) {
5616
+ this.methodData = { carrier_code: carrierCode, method, additional_data: [] };
5617
+ }
5618
+ /**
5619
+ * Sets the display name for the shipping method
5620
+ *
5621
+ * @param methodTitle - Display name for the shipping method
5622
+ * @returns The rate builder instance for method chaining
5623
+ */
5624
+ setMethodTitle(methodTitle) {
5625
+ this.methodData.method_title = methodTitle;
5626
+ return this;
5627
+ }
5628
+ /**
5629
+ * Sets the price charged to the customer
5630
+ *
5631
+ * @param price - Price charged to the customer
5632
+ * @returns The rate builder instance for method chaining
5633
+ */
5634
+ setPrice(price) {
5635
+ this.methodData.price = price;
5636
+ return this;
5637
+ }
5638
+ /**
5639
+ * Sets the cost to the merchant
5640
+ *
5641
+ * @param cost - Cost to the merchant
5642
+ * @returns The rate builder instance for method chaining
5643
+ */
5644
+ setCost(cost) {
5645
+ this.methodData.cost = cost;
5646
+ return this;
5647
+ }
5648
+ /**
5649
+ * Adds additional data to the shipping method
5650
+ *
5651
+ * @param key - Key for the additional data
5652
+ * @param value - Value for the additional data
5653
+ * @returns The rate builder instance for method chaining
5654
+ *
5655
+ * @example
5656
+ * ```typescript
5657
+ * rate.addAdditionalData('delivery_time', '3-5 business days')
5658
+ * .addAdditionalData('tracking_available', true);
5659
+ * ```
5660
+ */
5661
+ addAdditionalData(key, value) {
5662
+ const additionalDataItem = { key, value };
5663
+ this.methodData.additional_data?.push(additionalDataItem);
5664
+ return this;
5665
+ }
5666
+ /**
5667
+ * Gets and returns the shipping carrier method data
5668
+ *
5669
+ * @returns The shipping carrier method data
5670
+ */
5671
+ getData() {
5672
+ return this.methodData;
5673
+ }
5674
+ };
5675
+ __name(_ShippingCarrierMethod, "ShippingCarrierMethod");
5676
+ var ShippingCarrierMethod = _ShippingCarrierMethod;
5677
+ var method_default = ShippingCarrierMethod;
5678
+
5679
+ // src/commerce/shipping-carrier/index.ts
5680
+ var _ShippingCarrier = class _ShippingCarrier {
5681
+ constructor(code, callback) {
5682
+ this.addedMethods = [];
5683
+ this.removedMethods = [];
5684
+ this.validateCarrierCode(code);
5685
+ this.carrierData = {
5686
+ code,
5687
+ active: true,
5688
+ tracking_available: true,
5689
+ shipping_labels_available: true
5690
+ };
5691
+ this.addedMethods = [];
5692
+ this.removedMethods = [];
5693
+ if (callback) {
5694
+ callback(this);
5695
+ }
5696
+ }
5697
+ /**
5698
+ * Validates that the carrier code contains only alphanumeric characters and underscores
5699
+ *
5700
+ * @param code - Carrier code to validate
5701
+ * @throws Error if code is invalid
5702
+ */
5703
+ validateCarrierCode(code) {
5704
+ if (!code || code.trim() === "") {
5705
+ throw new Error("Carrier code cannot be empty");
5706
+ }
5707
+ const validPattern = /^[a-zA-Z0-9_]+$/;
5708
+ if (!validPattern.test(code)) {
5709
+ throw new Error("Carrier code must contain only alphanumeric characters and underscores");
5710
+ }
5711
+ }
5712
+ /**
5713
+ * Validates that the method code contains only alphanumeric characters and underscores
5714
+ *
5715
+ * @param method - Method code to validate
5716
+ * @throws Error if method code is invalid
5717
+ */
5718
+ validateMethodCode(method) {
5719
+ if (!method || method.trim() === "") {
5720
+ throw new Error("Method code cannot be empty");
5721
+ }
5722
+ const validPattern = /^[a-zA-Z0-9_]+$/;
5723
+ if (!validPattern.test(method)) {
5724
+ throw new Error("Method code must contain only alphanumeric characters and underscores");
5725
+ }
5726
+ }
5727
+ /**
5728
+ * Sets the title for the shipping carrier
5729
+ *
5730
+ * @param title - Display title for the carrier
5731
+ * @returns The builder instance for method chaining
5732
+ *
5733
+ * @example
5734
+ * ```typescript
5735
+ * carrier.setTitle('FedEx Express');
5736
+ * ```
5737
+ */
5738
+ setTitle(title) {
5739
+ this.carrierData.title = title;
5740
+ return this;
5741
+ }
5742
+ /**
5743
+ * Sets the stores for the shipping carrier
5744
+ *
5745
+ * @param stores - Array of store codes
5746
+ * @returns The builder instance for method chaining
5747
+ *
5748
+ * @example
5749
+ * ```typescript
5750
+ * carrier.setStores(['default', 'store1', 'store2']);
5751
+ * ```
5752
+ */
5753
+ setStores(stores) {
5754
+ this.carrierData.stores = stores;
5755
+ return this;
5756
+ }
5757
+ /**
5758
+ * Sets the countries for the shipping carrier
5759
+ *
5760
+ * @param countries - Array of country codes
5761
+ * @returns The builder instance for method chaining
5762
+ *
5763
+ * @example
5764
+ * ```typescript
5765
+ * carrier.setCountries(['US', 'CA', 'MX']);
5766
+ * ```
5767
+ */
5768
+ setCountries(countries) {
5769
+ this.carrierData.countries = countries;
5770
+ return this;
5771
+ }
5772
+ /**
5773
+ * Sets the sort order for the shipping carrier
5774
+ *
5775
+ * @param sortOrder - Sort order number
5776
+ * @returns The builder instance for method chaining
5777
+ *
5778
+ * @example
5779
+ * ```typescript
5780
+ * carrier.setSortOrder(10);
5781
+ * ```
5782
+ */
5783
+ setSortOrder(sortOrder) {
5784
+ this.carrierData.sort_order = sortOrder;
5785
+ return this;
5786
+ }
5787
+ /**
5788
+ * Sets the active status for the shipping carrier
5789
+ *
5790
+ * @param active - Active status
5791
+ * @returns The builder instance for method chaining
5792
+ *
5793
+ * @example
5794
+ * ```typescript
5795
+ * carrier.setActive(true);
5796
+ * carrier.setActive(false);
5797
+ * ```
5798
+ */
5799
+ setActive(active) {
5800
+ this.carrierData.active = active;
5801
+ return this;
5802
+ }
5803
+ /**
5804
+ * Sets the tracking availability for the shipping carrier
5805
+ *
5806
+ * @param trackingAvailable - Tracking availability status
5807
+ * @returns The builder instance for method chaining
5808
+ *
5809
+ * @example
5810
+ * ```typescript
5811
+ * carrier.setTrackingAvailable(true);
5812
+ * carrier.setTrackingAvailable(false);
5813
+ * ```
5814
+ */
5815
+ setTrackingAvailable(trackingAvailable) {
5816
+ this.carrierData.tracking_available = trackingAvailable;
5817
+ return this;
5818
+ }
5819
+ /**
5820
+ * Sets the shipping labels availability for the shipping carrier
5821
+ *
5822
+ * @param shippingLabelsAvailable - Shipping labels availability status
5823
+ * @returns The builder instance for method chaining
5824
+ *
5825
+ * @example
5826
+ * ```typescript
5827
+ * carrier.setShippingLabelsAvailable(true);
5828
+ * carrier.setShippingLabelsAvailable(false);
5829
+ * ```
5830
+ */
5831
+ setShippingLabelsAvailable(shippingLabelsAvailable) {
5832
+ this.carrierData.shipping_labels_available = shippingLabelsAvailable;
5833
+ return this;
5834
+ }
5835
+ /**
5836
+ * Sets the carrier data from a ShippingCarrierData object
5837
+ *
5838
+ * @param carrierData - Carrier data object
5839
+ * @returns The builder instance for method chaining
5840
+ *
5841
+ * @example
5842
+ * ```typescript
5843
+ * carrier.setData({
5844
+ * code: 'fedex',
5845
+ * title: 'FedEx Express',
5846
+ * stores: ['default'],
5847
+ * countries: ['US', 'CA'],
5848
+ * sort_order: 10,
5849
+ * active: true,
5850
+ * tracking_available: true,
5851
+ * shipping_labels_available: true
5852
+ * });
5853
+ * ```
5854
+ */
5855
+ setData(carrierData) {
5856
+ this.validateCarrierCode(carrierData.code);
5857
+ this.carrierData = { ...carrierData };
5858
+ return this;
5859
+ }
5860
+ /**
5861
+ * Adds a shipping method to the carrier using a callback pattern
5862
+ *
5863
+ * @param method - Unique method for the shipping rate
5864
+ * @param callback - Optional callback function to configure the method
5865
+ * @returns The builder instance for method chaining
5866
+ *
5867
+ * @example
5868
+ * ```typescript
5869
+ * builder.addMethod('standard', (method) => {
5870
+ * method.setMethodTitle('Standard Shipping')
5871
+ * .setPrice(9.99)
5872
+ * .setCost(5.00)
5873
+ * .addAdditionalData('delivery_time', '3-5 business days');
5874
+ * });
5875
+ * ```
5876
+ */
5877
+ addMethod(method, callback) {
5878
+ this.validateMethodCode(method);
5879
+ const methodBuilder = new method_default(this.carrierData.code, method);
5880
+ if (callback) {
5881
+ callback(methodBuilder);
5882
+ }
5883
+ this.addedMethods.push(methodBuilder.getData());
5884
+ return this;
5885
+ }
5886
+ /**
5887
+ * Removes a shipping method from the carrier
5888
+ *
5889
+ * @param method - Method code to remove
5890
+ * @returns The builder instance for method chaining
5891
+ *
5892
+ * @example
5893
+ * ```typescript
5894
+ * builder.removeMethod('express');
5895
+ * ```
5896
+ */
5897
+ removeMethod(method) {
5898
+ this.validateMethodCode(method);
5899
+ this.removedMethods.push(method);
5900
+ return this;
5901
+ }
5902
+ /**
5903
+ * Resets the carrier and re-initializes it with new code and optional callback
5904
+ *
5905
+ * @param code - Carrier code
5906
+ * @param callback - Optional callback function to configure the carrier
5907
+ * @returns The builder instance for method chaining
5908
+ *
5909
+ * @example
5910
+ * ```typescript
5911
+ * carrier.reset('ups', (carrier) => {
5912
+ * carrier.addMethod('ground', (method) => {
5913
+ * method.setMethodTitle('UPS Ground').setPrice(12.99).setCost(8.00);
5914
+ * });
5915
+ * });
5916
+ * ```
5917
+ */
5918
+ reset(code, callback) {
5919
+ this.validateCarrierCode(code);
5920
+ this.carrierData = {
5921
+ code,
5922
+ active: true,
5923
+ tracking_available: true,
5924
+ shipping_labels_available: true
5925
+ };
5926
+ this.addedMethods = [];
5927
+ this.removedMethods = [];
5928
+ if (callback) {
5929
+ callback(this);
5930
+ }
5931
+ return this;
5932
+ }
5933
+ /**
5934
+ * Gets and returns the shipping carrier data as a JSON object
5935
+ *
5936
+ * @returns The shipping carrier data
5937
+ *
5938
+ * @example
5939
+ * ```typescript
5940
+ * const carrierData = carrier.getData();
5941
+ * // Returns:
5942
+ * // {
5943
+ * // code: 'DPS',
5944
+ * // title: 'Demo Postal Service',
5945
+ * // stores: ['default'],
5946
+ * // countries: ['US', 'CA'],
5947
+ * // sort_order: 10,
5948
+ * // active: true,
5949
+ * // tracking_available: true,
5950
+ * // shipping_labels_available: true
5951
+ * // }
5952
+ * ```
5953
+ */
5954
+ getData() {
5955
+ return this.carrierData;
5956
+ }
5957
+ };
5958
+ __name(_ShippingCarrier, "ShippingCarrier");
5959
+ var ShippingCarrier = _ShippingCarrier;
5960
+ var shipping_carrier_default = ShippingCarrier;
5961
+
5962
+ // src/commerce/shipping-carrier/response/index.ts
5963
+ var _ShippingCarrierResponse = class _ShippingCarrierResponse {
5964
+ constructor(carrier) {
5965
+ this.carrier = carrier;
5966
+ }
5967
+ /**
5968
+ * Generates and returns an array of WebhookActionResponse operations
5969
+ *
5970
+ * @returns Array of WebhookActionResponse operations
5971
+ *
5972
+ * @example
5973
+ * ```typescript
5974
+ * const carrier = new ShippingCarrier('fedex');
5975
+ * const response = new ShippingCarrierResponse(carrier);
5976
+ * const operations = response.generate();
5977
+ * ```
5978
+ */
5979
+ generate() {
5980
+ const operations = [];
5981
+ const addedMethods = this.carrier["addedMethods"];
5982
+ for (const method of addedMethods) {
5983
+ operations.push(response_default2.add("result", method));
5984
+ }
5985
+ const removedMethods = this.carrier["removedMethods"];
5986
+ for (const method of removedMethods) {
5987
+ operations.push(response_default2.add("result", { method, remove: true }));
5988
+ }
5989
+ return operations;
5990
+ }
5991
+ };
5992
+ __name(_ShippingCarrierResponse, "ShippingCarrierResponse");
5993
+ var ShippingCarrierResponse = _ShippingCarrierResponse;
5994
+ var response_default3 = ShippingCarrierResponse;
5995
+
5996
+ // src/experience/admin-ui-sdk/index.ts
5997
+ var _AdminUiSdk = class _AdminUiSdk {
5998
+ /**
5999
+ * Creates a new AdminUiSdk instance
6000
+ * @param extensionId - Unique identifier for the extension
6001
+ * @throws {Error} If extensionId is empty or invalid
6002
+ */
6003
+ constructor(extensionId) {
6004
+ this.menuItems = [];
6005
+ if (!extensionId?.trim()) {
6006
+ throw new Error("Extension ID is required and cannot be empty");
6007
+ }
6008
+ const trimmedId = extensionId.trim();
6009
+ if (!this.isValidExtensionId(trimmedId)) {
6010
+ throw new Error(
6011
+ "Extension ID must be alphanumeric with underscores only (no spaces, hyphens, or special characters)"
6012
+ );
6013
+ }
6014
+ this.extensionId = trimmedId;
6015
+ }
6016
+ /**
6017
+ * Validates that an extension ID contains only alphanumeric characters and underscores
6018
+ * @param id - The extension ID to validate
6019
+ * @returns true if valid, false otherwise
6020
+ */
6021
+ isValidExtensionId(id) {
6022
+ return /^[a-zA-Z0-9_]+$/.test(id);
6023
+ }
6024
+ /**
6025
+ * Validates that a menu ID is valid (can contain :: separator for namespacing)
6026
+ * @param id - The menu ID to validate
6027
+ * @returns true if valid, false otherwise
6028
+ */
6029
+ isValidMenuId(id) {
6030
+ return /^[a-zA-Z0-9_:]+$/.test(id);
6031
+ }
6032
+ /**
6033
+ * Adds a menu item to the extension
6034
+ * @param id - Full identifier for the menu item (e.g., 'extensionId::menuItem')
6035
+ * @param title - Display title for the menu item
6036
+ * @param sortOrder - Sort order for menu positioning
6037
+ * @param parent - Parent menu identifier (optional, full ID like 'extensionId::parent')
6038
+ * @throws {Error} If parameters are invalid or ID already exists
6039
+ */
6040
+ addMenuItem(id, title, sortOrder, parent) {
6041
+ if (!id?.trim()) {
6042
+ throw new Error("Menu item ID is required and cannot be empty");
6043
+ }
6044
+ if (!this.isValidMenuId(id.trim())) {
6045
+ throw new Error(
6046
+ "Menu item ID must be alphanumeric with underscores and colons only (no spaces, hyphens, or other special characters)"
6047
+ );
6048
+ }
6049
+ if (!title?.trim()) {
6050
+ throw new Error("Menu item title is required and cannot be empty");
6051
+ }
6052
+ if (parent !== void 0 && !parent?.trim()) {
6053
+ throw new Error("Menu item parent cannot be empty if provided");
6054
+ }
6055
+ if (parent !== void 0 && !this.isValidMenuId(parent.trim())) {
6056
+ throw new Error(
6057
+ "Menu item parent must be alphanumeric with underscores and colons only (no spaces, hyphens, or other special characters)"
6058
+ );
6059
+ }
6060
+ if (typeof sortOrder !== "number" || sortOrder < 0) {
6061
+ throw new Error("Menu item sortOrder must be a non-negative number");
6062
+ }
6063
+ const trimmedId = id.trim();
6064
+ if (this.menuItems.some((item) => item.id === trimmedId)) {
6065
+ throw new Error(`Menu item with ID '${trimmedId}' already exists`);
6066
+ }
6067
+ const menuItem = {
6068
+ id: trimmedId,
6069
+ title: title.trim(),
6070
+ sortOrder
6071
+ };
6072
+ if (parent?.trim()) {
6073
+ menuItem.parent = parent.trim();
6074
+ }
6075
+ this.menuItems.push(menuItem);
6076
+ }
6077
+ /**
6078
+ * Adds a menu section to the extension
6079
+ * @param id - Full identifier for the menu section (e.g., 'extensionId::section')
6080
+ * @param title - Display title for the menu section
6081
+ * @param sortOrder - Sort order for section positioning
6082
+ * @param parent - Parent menu identifier (optional, full ID like 'Magento_Backend::system')
6083
+ * @throws {Error} If parameters are invalid or ID already exists
6084
+ */
6085
+ addMenuSection(id, title, sortOrder, parent) {
6086
+ if (!id?.trim()) {
6087
+ throw new Error("Menu section ID is required and cannot be empty");
6088
+ }
6089
+ if (!this.isValidMenuId(id.trim())) {
6090
+ throw new Error(
6091
+ "Menu section ID must be alphanumeric with underscores and colons only (no spaces, hyphens, or other special characters)"
6092
+ );
6093
+ }
6094
+ if (!title?.trim()) {
6095
+ throw new Error("Menu section title is required and cannot be empty");
6096
+ }
6097
+ if (parent !== void 0 && !parent?.trim()) {
6098
+ throw new Error("Menu section parent cannot be empty if provided");
6099
+ }
6100
+ if (parent !== void 0 && !this.isValidMenuId(parent.trim())) {
6101
+ throw new Error(
6102
+ "Menu section parent must be alphanumeric with underscores and colons only (no spaces, hyphens, or other special characters)"
6103
+ );
6104
+ }
6105
+ if (typeof sortOrder !== "number" || sortOrder < 0) {
6106
+ throw new Error("Menu section sortOrder must be a non-negative number");
6107
+ }
6108
+ const trimmedId = id.trim();
6109
+ if (this.menuItems.some((item) => item.id === trimmedId)) {
6110
+ throw new Error(`Menu item with ID '${trimmedId}' already exists`);
6111
+ }
6112
+ const menuSection = {
6113
+ id: trimmedId,
6114
+ title: title.trim(),
6115
+ sortOrder,
6116
+ isSection: true
6117
+ };
6118
+ if (parent?.trim()) {
6119
+ menuSection.parent = parent.trim();
6120
+ }
6121
+ this.menuItems.push(menuSection);
6122
+ }
6123
+ /**
6124
+ * Sets the page title for the extension
6125
+ * @param title - The page title
6126
+ * @throws {Error} If title is empty or invalid
6127
+ */
6128
+ addPage(title) {
6129
+ if (!title?.trim()) {
6130
+ throw new Error("Page title is required and cannot be empty");
6131
+ }
6132
+ this.pageTitle = title.trim();
6133
+ }
6134
+ /**
6135
+ * Gets the complete registration object for the extension
6136
+ * @returns The registration object with optional menu items and page configuration
6137
+ */
6138
+ getRegistration() {
6139
+ const registration = {};
6140
+ if (this.menuItems.length > 0) {
6141
+ registration.menuItems = [...this.menuItems];
6142
+ }
6143
+ if (this.pageTitle) {
6144
+ registration.page = {
6145
+ title: this.pageTitle
6146
+ };
6147
+ }
6148
+ return {
6149
+ registration
6150
+ };
6151
+ }
6152
+ };
6153
+ __name(_AdminUiSdk, "AdminUiSdk");
6154
+ var AdminUiSdk = _AdminUiSdk;
4997
6155
  // Annotate the CommonJS export names for ESM import in node:
4998
6156
  0 && (module.exports = {
6157
+ AdminUiSdk,
4999
6158
  AdobeAuth,
5000
6159
  AdobeCommerceClient,
5001
6160
  BasicAuthConnection,
@@ -5019,10 +6178,18 @@ var ims_connection_default = ImsConnection;
5019
6178
  OpenwhiskAction,
5020
6179
  Parameters,
5021
6180
  ProviderManager,
6181
+ PublishEvent,
5022
6182
  RegistrationManager,
5023
6183
  RestClient,
5024
6184
  RuntimeAction,
5025
6185
  RuntimeActionResponse,
5026
- Validator
6186
+ ShippingCarrier,
6187
+ ShippingCarrierMethod,
6188
+ ShippingCarrierResponse,
6189
+ SignatureVerification,
6190
+ Validator,
6191
+ WebhookAction,
6192
+ WebhookActionOperation,
6193
+ WebhookActionResponse
5027
6194
  });
5028
6195
  //# sourceMappingURL=index.js.map