@adobe-commerce/aio-toolkit 1.0.1 → 1.0.3
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 +90 -0
- package/README.md +208 -17
- package/dist/index.d.mts +61 -9
- package/dist/index.d.ts +61 -9
- package/dist/index.js +550 -47
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +533 -32
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -2
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,6 +55,7 @@ __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,
|
|
@@ -484,39 +486,44 @@ var _FileRepository = class _FileRepository {
|
|
|
484
486
|
/**
|
|
485
487
|
* Saves a file record to the repository
|
|
486
488
|
* @param payload - The data to save
|
|
487
|
-
* @
|
|
489
|
+
* @param id - Optional ID for the file (sanitized to alphanumeric + underscore, takes precedence over payload.id)
|
|
490
|
+
* @returns Promise<string | null> The filename on success, null on failure
|
|
488
491
|
*/
|
|
489
|
-
async save(payload = {}) {
|
|
492
|
+
async save(payload = {}, id) {
|
|
490
493
|
try {
|
|
491
494
|
const filesLib = await this.getFiles();
|
|
492
|
-
let
|
|
493
|
-
if (
|
|
494
|
-
|
|
495
|
+
let fileId;
|
|
496
|
+
if (id) {
|
|
497
|
+
fileId = this.sanitizeFileId(id);
|
|
498
|
+
} else if ("id" in payload && payload.id !== void 0) {
|
|
499
|
+
fileId = String(payload.id);
|
|
500
|
+
} else {
|
|
501
|
+
fileId = String((/* @__PURE__ */ new Date()).getTime());
|
|
495
502
|
}
|
|
496
|
-
const filepath = `${this.filepath}/${
|
|
503
|
+
const filepath = `${this.filepath}/${fileId}.json`;
|
|
497
504
|
const existingFile = await filesLib.list(filepath);
|
|
498
505
|
if (existingFile.length) {
|
|
499
506
|
const buffer = await filesLib.read(filepath);
|
|
500
507
|
const existingData = JSON.parse(buffer.toString());
|
|
501
508
|
payload = {
|
|
502
509
|
...payload,
|
|
503
|
-
|
|
510
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
504
511
|
};
|
|
505
512
|
payload = { ...existingData, ...payload };
|
|
506
513
|
await filesLib.delete(filepath);
|
|
507
514
|
} else {
|
|
508
515
|
payload = {
|
|
509
516
|
...payload,
|
|
510
|
-
id:
|
|
511
|
-
|
|
512
|
-
|
|
517
|
+
id: fileId,
|
|
518
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
519
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
513
520
|
};
|
|
514
521
|
}
|
|
515
522
|
await filesLib.write(filepath, JSON.stringify(payload));
|
|
516
|
-
return
|
|
523
|
+
return fileId;
|
|
517
524
|
} catch (error) {
|
|
518
525
|
console.error("Error saving file:", error);
|
|
519
|
-
return
|
|
526
|
+
return null;
|
|
520
527
|
}
|
|
521
528
|
}
|
|
522
529
|
/**
|
|
@@ -531,6 +538,21 @@ var _FileRepository = class _FileRepository {
|
|
|
531
538
|
}
|
|
532
539
|
return await this.list();
|
|
533
540
|
}
|
|
541
|
+
/**
|
|
542
|
+
* Sanitizes the file ID to contain only alphanumeric characters and underscores
|
|
543
|
+
* @param id - The ID to sanitize
|
|
544
|
+
* @returns Sanitized ID with invalid characters replaced by underscores
|
|
545
|
+
*/
|
|
546
|
+
sanitizeFileId(id) {
|
|
547
|
+
if (!id || typeof id !== "string") {
|
|
548
|
+
return String((/* @__PURE__ */ new Date()).getTime());
|
|
549
|
+
}
|
|
550
|
+
const sanitized = id.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
551
|
+
if (!sanitized || /^_+$/.test(sanitized)) {
|
|
552
|
+
return String((/* @__PURE__ */ new Date()).getTime());
|
|
553
|
+
}
|
|
554
|
+
return sanitized;
|
|
555
|
+
}
|
|
534
556
|
/**
|
|
535
557
|
* Initializes and returns the Files library instance
|
|
536
558
|
* @returns Promise<any> Initialized Files library instance
|
|
@@ -546,6 +568,143 @@ __name(_FileRepository, "FileRepository");
|
|
|
546
568
|
var FileRepository = _FileRepository;
|
|
547
569
|
var file_repository_default = FileRepository;
|
|
548
570
|
|
|
571
|
+
// src/framework/publish-event/index.ts
|
|
572
|
+
var import_aio_sdk5 = require("@adobe/aio-sdk");
|
|
573
|
+
var import_cloudevents = require("cloudevents");
|
|
574
|
+
var import_uuid = require("uuid");
|
|
575
|
+
|
|
576
|
+
// src/framework/custom-logger/index.ts
|
|
577
|
+
var _CustomLogger = class _CustomLogger {
|
|
578
|
+
/**
|
|
579
|
+
* @param logger - External logger instance (can be null)
|
|
580
|
+
*/
|
|
581
|
+
constructor(logger = null) {
|
|
582
|
+
this.logger = logger;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Log debug message if logger is available
|
|
586
|
+
* @param message - Debug message to log
|
|
587
|
+
*/
|
|
588
|
+
debug(message) {
|
|
589
|
+
if (this.logger && typeof this.logger.debug === "function") {
|
|
590
|
+
this.logger.debug(message);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Log info message if logger is available
|
|
595
|
+
* @param message - Info message to log
|
|
596
|
+
*/
|
|
597
|
+
info(message) {
|
|
598
|
+
if (this.logger && typeof this.logger.info === "function") {
|
|
599
|
+
this.logger.info(message);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Log error message if logger is available
|
|
604
|
+
* @param message - Error message to log
|
|
605
|
+
*/
|
|
606
|
+
error(message) {
|
|
607
|
+
if (this.logger && typeof this.logger.error === "function") {
|
|
608
|
+
this.logger.error(message);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Get the underlying logger instance
|
|
613
|
+
* @returns the logger instance or null
|
|
614
|
+
*/
|
|
615
|
+
getLogger() {
|
|
616
|
+
return this.logger;
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
__name(_CustomLogger, "CustomLogger");
|
|
620
|
+
var CustomLogger = _CustomLogger;
|
|
621
|
+
var custom_logger_default = CustomLogger;
|
|
622
|
+
|
|
623
|
+
// src/framework/publish-event/index.ts
|
|
624
|
+
var _PublishEvent = class _PublishEvent {
|
|
625
|
+
/**
|
|
626
|
+
* Creates a new PublishEvent instance
|
|
627
|
+
*
|
|
628
|
+
* @param imsOrgId - Adobe IMS Organization ID
|
|
629
|
+
* @param apiKey - Adobe API Key (Client ID)
|
|
630
|
+
* @param accessToken - Adobe Access Token
|
|
631
|
+
* @param logger - Optional logger instance
|
|
632
|
+
*/
|
|
633
|
+
constructor(imsOrgId, apiKey, accessToken, logger = null) {
|
|
634
|
+
if (!imsOrgId?.trim()) {
|
|
635
|
+
throw new Error("imsOrgId is required and cannot be empty");
|
|
636
|
+
}
|
|
637
|
+
if (!apiKey?.trim()) {
|
|
638
|
+
throw new Error("apiKey is required and cannot be empty");
|
|
639
|
+
}
|
|
640
|
+
if (!accessToken?.trim()) {
|
|
641
|
+
throw new Error("accessToken is required and cannot be empty");
|
|
642
|
+
}
|
|
643
|
+
this.imsOrgId = imsOrgId;
|
|
644
|
+
this.apiKey = apiKey;
|
|
645
|
+
this.accessToken = accessToken;
|
|
646
|
+
this.customLogger = new custom_logger_default(logger);
|
|
647
|
+
this.customLogger.debug("PublishEvent initialized with valid configuration");
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Publishes a CloudEvent to Adobe I/O Events
|
|
651
|
+
*
|
|
652
|
+
* @param providerId - The Adobe I/O Events provider ID
|
|
653
|
+
* @param eventCode - The event type identifier (e.g., 'commerce.order.created')
|
|
654
|
+
* @param payload - The event payload data
|
|
655
|
+
* @param subject - Optional subject for the event
|
|
656
|
+
* @returns Promise<PublishEventResult> - The publish result
|
|
657
|
+
*
|
|
658
|
+
* @throws Error when providerId or eventCode is invalid or publishing fails
|
|
659
|
+
*/
|
|
660
|
+
async execute(providerId, eventCode, payload, subject) {
|
|
661
|
+
try {
|
|
662
|
+
if (!providerId?.trim()) {
|
|
663
|
+
throw new Error("providerId is required and cannot be empty");
|
|
664
|
+
}
|
|
665
|
+
if (!eventCode?.trim()) {
|
|
666
|
+
throw new Error("eventCode is required and cannot be empty");
|
|
667
|
+
}
|
|
668
|
+
if (payload === null || payload === void 0) {
|
|
669
|
+
throw new Error("payload is required");
|
|
670
|
+
}
|
|
671
|
+
this.customLogger.info(`Publishing event to provider: ${providerId}`);
|
|
672
|
+
const eventId = (0, import_uuid.v4)();
|
|
673
|
+
const cloudEvent = new import_cloudevents.CloudEvent({
|
|
674
|
+
id: eventId,
|
|
675
|
+
source: `urn:uuid:${providerId}`,
|
|
676
|
+
datacontenttype: "application/json",
|
|
677
|
+
type: eventCode,
|
|
678
|
+
data: payload,
|
|
679
|
+
...subject && { subject }
|
|
680
|
+
});
|
|
681
|
+
this.customLogger.debug(`Constructed CloudEvent with ID: ${eventId}`);
|
|
682
|
+
const eventsClient = await import_aio_sdk5.Events.init(this.imsOrgId, this.apiKey, this.accessToken);
|
|
683
|
+
this.customLogger.debug("Adobe I/O Events client initialized successfully");
|
|
684
|
+
await eventsClient.publishEvent(cloudEvent);
|
|
685
|
+
const publishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
686
|
+
this.customLogger.info(`Event published successfully with ID: ${eventId}`);
|
|
687
|
+
return {
|
|
688
|
+
eventId,
|
|
689
|
+
status: "published",
|
|
690
|
+
publishedAt
|
|
691
|
+
};
|
|
692
|
+
} catch (error) {
|
|
693
|
+
this.customLogger.error(`Failed to publish event: ${error.message}`);
|
|
694
|
+
return {
|
|
695
|
+
eventId: (0, import_uuid.v4)(),
|
|
696
|
+
// Generate ID for tracking even failed events
|
|
697
|
+
status: "failed",
|
|
698
|
+
publishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
699
|
+
error: error.message
|
|
700
|
+
};
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
};
|
|
704
|
+
__name(_PublishEvent, "PublishEvent");
|
|
705
|
+
var PublishEvent = _PublishEvent;
|
|
706
|
+
var publish_event_default = PublishEvent;
|
|
707
|
+
|
|
549
708
|
// src/integration/bearer-token/index.ts
|
|
550
709
|
var _BearerToken = class _BearerToken {
|
|
551
710
|
/**
|
|
@@ -708,13 +867,32 @@ var _RestClient = class _RestClient {
|
|
|
708
867
|
headers
|
|
709
868
|
};
|
|
710
869
|
if (payload !== null) {
|
|
870
|
+
let body;
|
|
871
|
+
let contentType;
|
|
872
|
+
if (payload instanceof URLSearchParams) {
|
|
873
|
+
body = payload.toString();
|
|
874
|
+
contentType = headers["Content-Type"] || "application/x-www-form-urlencoded";
|
|
875
|
+
} else if (typeof FormData !== "undefined" && payload instanceof FormData) {
|
|
876
|
+
body = payload;
|
|
877
|
+
contentType = headers["Content-Type"];
|
|
878
|
+
} else if (typeof payload === "string") {
|
|
879
|
+
body = payload;
|
|
880
|
+
contentType = headers["Content-Type"] || "text/plain";
|
|
881
|
+
} else if (payload instanceof Buffer || payload instanceof ArrayBuffer || typeof Uint8Array !== "undefined" && payload instanceof Uint8Array) {
|
|
882
|
+
body = payload;
|
|
883
|
+
contentType = headers["Content-Type"] || "application/octet-stream";
|
|
884
|
+
} else {
|
|
885
|
+
body = JSON.stringify(payload);
|
|
886
|
+
contentType = headers["Content-Type"] || "application/json";
|
|
887
|
+
}
|
|
888
|
+
const requestHeaders = { ...headers };
|
|
889
|
+
if (contentType) {
|
|
890
|
+
requestHeaders["Content-Type"] = contentType;
|
|
891
|
+
}
|
|
711
892
|
options = {
|
|
712
893
|
...options,
|
|
713
|
-
body
|
|
714
|
-
headers:
|
|
715
|
-
...headers,
|
|
716
|
-
"Content-Type": "application/json"
|
|
717
|
-
}
|
|
894
|
+
body,
|
|
895
|
+
headers: requestHeaders
|
|
718
896
|
};
|
|
719
897
|
}
|
|
720
898
|
return await (0, import_node_fetch.default)(endpoint, options);
|
|
@@ -844,7 +1022,7 @@ var RestClient = _RestClient;
|
|
|
844
1022
|
var rest_client_default = RestClient;
|
|
845
1023
|
|
|
846
1024
|
// src/integration/onboard-events/index.ts
|
|
847
|
-
var
|
|
1025
|
+
var import_aio_sdk6 = require("@adobe/aio-sdk");
|
|
848
1026
|
|
|
849
1027
|
// src/io-events/types.ts
|
|
850
1028
|
var IoEventsGlobals = {
|
|
@@ -4159,7 +4337,7 @@ var _OnboardEvents = class _OnboardEvents {
|
|
|
4159
4337
|
throw new Error("Access token is required");
|
|
4160
4338
|
}
|
|
4161
4339
|
const loggerName = projectName.toLowerCase().replace(/[^a-z0-9\s-_]/g, "").replace(/\s+/g, "-").replace(/_{2,}/g, "_").replace(/-{2,}/g, "-").trim().concat("-onboard-events");
|
|
4162
|
-
this.logger =
|
|
4340
|
+
this.logger = import_aio_sdk6.Core.Logger(loggerName, { level: "debug" });
|
|
4163
4341
|
this.createProviders = new create_providers_default(
|
|
4164
4342
|
consumerId,
|
|
4165
4343
|
projectId,
|
|
@@ -4355,7 +4533,7 @@ var OnboardEvents = _OnboardEvents;
|
|
|
4355
4533
|
var onboard_events_default = OnboardEvents;
|
|
4356
4534
|
|
|
4357
4535
|
// src/integration/infinite-loop-breaker/index.ts
|
|
4358
|
-
var
|
|
4536
|
+
var import_aio_sdk7 = require("@adobe/aio-sdk");
|
|
4359
4537
|
var import_crypto2 = __toESM(require("crypto"));
|
|
4360
4538
|
var _InfiniteLoopBreaker = class _InfiniteLoopBreaker {
|
|
4361
4539
|
// seconds
|
|
@@ -4373,7 +4551,7 @@ var _InfiniteLoopBreaker = class _InfiniteLoopBreaker {
|
|
|
4373
4551
|
event
|
|
4374
4552
|
}) {
|
|
4375
4553
|
const logLevel = process.env.LOG_LEVEL || "info";
|
|
4376
|
-
const logger =
|
|
4554
|
+
const logger = import_aio_sdk7.Core.Logger("infiniteLoopBreaker", { level: logLevel });
|
|
4377
4555
|
logger.debug(`Checking for potential infinite loop for event: ${event}`);
|
|
4378
4556
|
if (!eventTypes.includes(event)) {
|
|
4379
4557
|
logger.debug(`Event type ${event} is not in the infinite loop event types list`);
|
|
@@ -4381,7 +4559,7 @@ var _InfiniteLoopBreaker = class _InfiniteLoopBreaker {
|
|
|
4381
4559
|
}
|
|
4382
4560
|
const key = typeof keyFn === "function" ? keyFn() : keyFn;
|
|
4383
4561
|
const data = typeof fingerprintFn === "function" ? fingerprintFn() : fingerprintFn;
|
|
4384
|
-
const state = await
|
|
4562
|
+
const state = await import_aio_sdk7.State.init();
|
|
4385
4563
|
const persistedFingerPrint = await state.get(key);
|
|
4386
4564
|
if (!persistedFingerPrint) {
|
|
4387
4565
|
logger.debug(`No persisted fingerprint found for key ${key}`);
|
|
@@ -4402,7 +4580,7 @@ var _InfiniteLoopBreaker = class _InfiniteLoopBreaker {
|
|
|
4402
4580
|
static async storeFingerPrint(keyFn, fingerprintFn, ttl) {
|
|
4403
4581
|
const key = typeof keyFn === "function" ? keyFn() : keyFn;
|
|
4404
4582
|
const data = typeof fingerprintFn === "function" ? fingerprintFn() : fingerprintFn;
|
|
4405
|
-
const state = await
|
|
4583
|
+
const state = await import_aio_sdk7.State.init();
|
|
4406
4584
|
await state.put(key, _InfiniteLoopBreaker.fingerPrint(data), {
|
|
4407
4585
|
ttl: ttl !== void 0 ? ttl : _InfiniteLoopBreaker.DEFAULT_INFINITE_LOOP_BREAKER_TTL
|
|
4408
4586
|
});
|
|
@@ -4495,7 +4673,7 @@ var AdobeAuth = _AdobeAuth;
|
|
|
4495
4673
|
var adobe_auth_default = AdobeAuth;
|
|
4496
4674
|
|
|
4497
4675
|
// src/commerce/adobe-commerce-client/index.ts
|
|
4498
|
-
var
|
|
4676
|
+
var import_aio_sdk8 = require("@adobe/aio-sdk");
|
|
4499
4677
|
var import_got = __toESM(require("got"));
|
|
4500
4678
|
var _AdobeCommerceClient = class _AdobeCommerceClient {
|
|
4501
4679
|
/**
|
|
@@ -4510,7 +4688,7 @@ var _AdobeCommerceClient = class _AdobeCommerceClient {
|
|
|
4510
4688
|
this.baseUrl = baseUrl;
|
|
4511
4689
|
this.connection = connection;
|
|
4512
4690
|
if (logger === null) {
|
|
4513
|
-
logger =
|
|
4691
|
+
logger = import_aio_sdk8.Core.Logger("adobe-commerce-client", {
|
|
4514
4692
|
level: "debug"
|
|
4515
4693
|
});
|
|
4516
4694
|
}
|
|
@@ -4637,10 +4815,10 @@ var AdobeCommerceClient = _AdobeCommerceClient;
|
|
|
4637
4815
|
var adobe_commerce_client_default = AdobeCommerceClient;
|
|
4638
4816
|
|
|
4639
4817
|
// src/commerce/adobe-commerce-client/basic-auth-connection/index.ts
|
|
4640
|
-
var
|
|
4818
|
+
var import_aio_sdk10 = require("@adobe/aio-sdk");
|
|
4641
4819
|
|
|
4642
4820
|
// src/commerce/adobe-commerce-client/basic-auth-connection/generate-basic-auth-token/index.ts
|
|
4643
|
-
var
|
|
4821
|
+
var import_aio_sdk9 = require("@adobe/aio-sdk");
|
|
4644
4822
|
var _GenerateBasicAuthToken = class _GenerateBasicAuthToken {
|
|
4645
4823
|
/**
|
|
4646
4824
|
* @param baseUrl
|
|
@@ -4654,7 +4832,7 @@ var _GenerateBasicAuthToken = class _GenerateBasicAuthToken {
|
|
|
4654
4832
|
this.password = password;
|
|
4655
4833
|
this.key = "adobe_commerce_basic_auth_token";
|
|
4656
4834
|
if (logger === null) {
|
|
4657
|
-
logger =
|
|
4835
|
+
logger = import_aio_sdk9.Core.Logger("adobe-commerce-client", {
|
|
4658
4836
|
level: "debug"
|
|
4659
4837
|
});
|
|
4660
4838
|
}
|
|
@@ -4686,7 +4864,7 @@ var _GenerateBasicAuthToken = class _GenerateBasicAuthToken {
|
|
|
4686
4864
|
* @return TokenResult | null
|
|
4687
4865
|
*/
|
|
4688
4866
|
async getCommerceToken() {
|
|
4689
|
-
const endpoint = this.
|
|
4867
|
+
const endpoint = this.createTokenEndpoint();
|
|
4690
4868
|
this.logger.debug(`Endpoint: ${endpoint}`);
|
|
4691
4869
|
try {
|
|
4692
4870
|
const restClient = new rest_client_default();
|
|
@@ -4732,6 +4910,19 @@ var _GenerateBasicAuthToken = class _GenerateBasicAuthToken {
|
|
|
4732
4910
|
return null;
|
|
4733
4911
|
}
|
|
4734
4912
|
}
|
|
4913
|
+
/**
|
|
4914
|
+
* Create the Adobe Commerce integration admin token endpoint.
|
|
4915
|
+
* Handles cases where baseUrl may or may not already include /rest.
|
|
4916
|
+
* @return string
|
|
4917
|
+
*/
|
|
4918
|
+
createTokenEndpoint() {
|
|
4919
|
+
const normalizedBaseUrl = this.baseUrl.replace(/\/+$/, "");
|
|
4920
|
+
if (normalizedBaseUrl.endsWith("/rest")) {
|
|
4921
|
+
return `${normalizedBaseUrl}/V1/integration/admin/token`;
|
|
4922
|
+
} else {
|
|
4923
|
+
return `${normalizedBaseUrl}/rest/V1/integration/admin/token`;
|
|
4924
|
+
}
|
|
4925
|
+
}
|
|
4735
4926
|
/**
|
|
4736
4927
|
* @param endpoint
|
|
4737
4928
|
* @return string
|
|
@@ -4782,7 +4973,7 @@ var _GenerateBasicAuthToken = class _GenerateBasicAuthToken {
|
|
|
4782
4973
|
async getState() {
|
|
4783
4974
|
if (this.state === void 0) {
|
|
4784
4975
|
try {
|
|
4785
|
-
this.state = await
|
|
4976
|
+
this.state = await import_aio_sdk9.State.init();
|
|
4786
4977
|
} catch (error) {
|
|
4787
4978
|
this.logger.debug("State API initialization failed, running without caching");
|
|
4788
4979
|
this.state = null;
|
|
@@ -4808,7 +4999,7 @@ var _BasicAuthConnection = class _BasicAuthConnection {
|
|
|
4808
4999
|
this.username = username;
|
|
4809
5000
|
this.password = password;
|
|
4810
5001
|
if (logger === null) {
|
|
4811
|
-
logger =
|
|
5002
|
+
logger = import_aio_sdk10.Core.Logger("adobe-commerce-client", {
|
|
4812
5003
|
level: "debug"
|
|
4813
5004
|
});
|
|
4814
5005
|
}
|
|
@@ -4838,7 +5029,7 @@ var BasicAuthConnection = _BasicAuthConnection;
|
|
|
4838
5029
|
var basic_auth_connection_default = BasicAuthConnection;
|
|
4839
5030
|
|
|
4840
5031
|
// src/commerce/adobe-commerce-client/oauth1a-connection/index.ts
|
|
4841
|
-
var
|
|
5032
|
+
var import_aio_sdk11 = require("@adobe/aio-sdk");
|
|
4842
5033
|
var import_oauth_1 = __toESM(require("oauth-1.0a"));
|
|
4843
5034
|
var crypto2 = __toESM(require("crypto"));
|
|
4844
5035
|
var _Oauth1aConnection = class _Oauth1aConnection {
|
|
@@ -4855,7 +5046,7 @@ var _Oauth1aConnection = class _Oauth1aConnection {
|
|
|
4855
5046
|
this.accessToken = accessToken;
|
|
4856
5047
|
this.accessTokenSecret = accessTokenSecret;
|
|
4857
5048
|
if (logger === null) {
|
|
4858
|
-
logger =
|
|
5049
|
+
logger = import_aio_sdk11.Core.Logger("adobe-commerce-client", {
|
|
4859
5050
|
level: "debug"
|
|
4860
5051
|
});
|
|
4861
5052
|
}
|
|
@@ -4902,8 +5093,161 @@ __name(_Oauth1aConnection, "Oauth1aConnection");
|
|
|
4902
5093
|
var Oauth1aConnection = _Oauth1aConnection;
|
|
4903
5094
|
var oauth1a_connection_default = Oauth1aConnection;
|
|
4904
5095
|
|
|
5096
|
+
// src/commerce/adobe-commerce-client/ims-connection/generate-ims-token/index.ts
|
|
5097
|
+
var import_aio_sdk12 = require("@adobe/aio-sdk");
|
|
5098
|
+
var _GenerateImsToken = class _GenerateImsToken {
|
|
5099
|
+
/**
|
|
5100
|
+
* @param clientId
|
|
5101
|
+
* @param clientSecret
|
|
5102
|
+
* @param technicalAccountId
|
|
5103
|
+
* @param technicalAccountEmail
|
|
5104
|
+
* @param imsOrgId
|
|
5105
|
+
* @param scopes
|
|
5106
|
+
* @param logger
|
|
5107
|
+
*/
|
|
5108
|
+
constructor(clientId, clientSecret, technicalAccountId, technicalAccountEmail, imsOrgId, scopes, logger = null) {
|
|
5109
|
+
this.key = "adobe_ims_auth_token";
|
|
5110
|
+
this.tokenContext = "adobe-commerce-client";
|
|
5111
|
+
this.clientId = clientId;
|
|
5112
|
+
this.clientSecret = clientSecret;
|
|
5113
|
+
this.technicalAccountId = technicalAccountId;
|
|
5114
|
+
this.technicalAccountEmail = technicalAccountEmail;
|
|
5115
|
+
this.imsOrgId = imsOrgId;
|
|
5116
|
+
this.scopes = scopes;
|
|
5117
|
+
this.customLogger = new custom_logger_default(logger);
|
|
5118
|
+
}
|
|
5119
|
+
/**
|
|
5120
|
+
* @return string | null
|
|
5121
|
+
*/
|
|
5122
|
+
async execute() {
|
|
5123
|
+
try {
|
|
5124
|
+
this.customLogger.info("Starting IMS token generation/retrieval process");
|
|
5125
|
+
const currentValue = await this.getValue();
|
|
5126
|
+
if (currentValue !== null) {
|
|
5127
|
+
this.customLogger.info("Found cached IMS token, returning cached value");
|
|
5128
|
+
return currentValue;
|
|
5129
|
+
}
|
|
5130
|
+
this.customLogger.info("No cached token found, generating new IMS token");
|
|
5131
|
+
let result = {
|
|
5132
|
+
token: null,
|
|
5133
|
+
expire_in: 86399
|
|
5134
|
+
// Default fallback, will be overridden by actual token expiry
|
|
5135
|
+
};
|
|
5136
|
+
const response = await this.getImsToken();
|
|
5137
|
+
if (response !== null) {
|
|
5138
|
+
result = response;
|
|
5139
|
+
}
|
|
5140
|
+
if (result.token !== null) {
|
|
5141
|
+
this.customLogger.info(`Generated new IMS token, caching for ${result.expire_in} seconds`);
|
|
5142
|
+
await this.setValue(result);
|
|
5143
|
+
}
|
|
5144
|
+
return result.token;
|
|
5145
|
+
} catch (error) {
|
|
5146
|
+
this.customLogger.error(`Failed to execute IMS token generation: ${error.message}`);
|
|
5147
|
+
return null;
|
|
5148
|
+
}
|
|
5149
|
+
}
|
|
5150
|
+
/**
|
|
5151
|
+
* @return ImsTokenResult | null
|
|
5152
|
+
*/
|
|
5153
|
+
async getImsToken() {
|
|
5154
|
+
try {
|
|
5155
|
+
this.customLogger.debug(`Calling AdobeAuth.getToken with context: ${this.tokenContext}`);
|
|
5156
|
+
const token = await adobe_auth_default.getToken(
|
|
5157
|
+
this.clientId,
|
|
5158
|
+
this.clientSecret,
|
|
5159
|
+
this.technicalAccountId,
|
|
5160
|
+
this.technicalAccountEmail,
|
|
5161
|
+
this.imsOrgId,
|
|
5162
|
+
this.scopes,
|
|
5163
|
+
this.tokenContext
|
|
5164
|
+
);
|
|
5165
|
+
if (token !== null && token !== void 0) {
|
|
5166
|
+
this.customLogger.debug("Received token from AdobeAuth, parsing with BearerToken.info");
|
|
5167
|
+
const tokenInfo = bearer_token_default.info(token);
|
|
5168
|
+
if (!tokenInfo.isValid) {
|
|
5169
|
+
this.customLogger.error("Received invalid or expired token from IMS");
|
|
5170
|
+
return null;
|
|
5171
|
+
}
|
|
5172
|
+
const expireInSeconds = tokenInfo.timeUntilExpiry ? Math.floor(tokenInfo.timeUntilExpiry / 1e3) : 86399;
|
|
5173
|
+
this.customLogger.debug(`Token expires in ${expireInSeconds} seconds`);
|
|
5174
|
+
return {
|
|
5175
|
+
token,
|
|
5176
|
+
expire_in: expireInSeconds
|
|
5177
|
+
};
|
|
5178
|
+
}
|
|
5179
|
+
this.customLogger.error("Received null or undefined token from IMS");
|
|
5180
|
+
return null;
|
|
5181
|
+
} catch (error) {
|
|
5182
|
+
this.customLogger.error(`Failed to get IMS token: ${error.message}`);
|
|
5183
|
+
return null;
|
|
5184
|
+
}
|
|
5185
|
+
}
|
|
5186
|
+
/**
|
|
5187
|
+
* @param result
|
|
5188
|
+
* @return boolean
|
|
5189
|
+
*/
|
|
5190
|
+
async setValue(result) {
|
|
5191
|
+
try {
|
|
5192
|
+
const state = await this.getState();
|
|
5193
|
+
if (state === null) {
|
|
5194
|
+
this.customLogger.info("State API not available, skipping token caching");
|
|
5195
|
+
return true;
|
|
5196
|
+
}
|
|
5197
|
+
const ttlWithBuffer = Math.max(result.expire_in - 300, 60);
|
|
5198
|
+
this.customLogger.debug(
|
|
5199
|
+
`Caching IMS token with TTL: ${ttlWithBuffer} seconds (original: ${result.expire_in})`
|
|
5200
|
+
);
|
|
5201
|
+
await state.put(this.key, result.token, { ttl: ttlWithBuffer });
|
|
5202
|
+
return true;
|
|
5203
|
+
} catch (error) {
|
|
5204
|
+
this.customLogger.error(`Failed to cache IMS token: ${error.message}`);
|
|
5205
|
+
return true;
|
|
5206
|
+
}
|
|
5207
|
+
}
|
|
5208
|
+
/**
|
|
5209
|
+
* @return string | null
|
|
5210
|
+
*/
|
|
5211
|
+
async getValue() {
|
|
5212
|
+
try {
|
|
5213
|
+
this.customLogger.debug("Checking for cached IMS token");
|
|
5214
|
+
const state = await this.getState();
|
|
5215
|
+
if (state === null) {
|
|
5216
|
+
this.customLogger.debug("State API not available, cannot retrieve cached token");
|
|
5217
|
+
return null;
|
|
5218
|
+
}
|
|
5219
|
+
const value = await state.get(this.key);
|
|
5220
|
+
if (value !== void 0 && value.value) {
|
|
5221
|
+
this.customLogger.debug("Found cached IMS token");
|
|
5222
|
+
return value.value;
|
|
5223
|
+
}
|
|
5224
|
+
this.customLogger.debug("No cached IMS token found");
|
|
5225
|
+
} catch (error) {
|
|
5226
|
+
this.customLogger.error(`Failed to retrieve cached IMS token: ${error.message}`);
|
|
5227
|
+
}
|
|
5228
|
+
return null;
|
|
5229
|
+
}
|
|
5230
|
+
/**
|
|
5231
|
+
* @return any
|
|
5232
|
+
*/
|
|
5233
|
+
async getState() {
|
|
5234
|
+
if (this.state === void 0) {
|
|
5235
|
+
try {
|
|
5236
|
+
this.customLogger.debug("Initializing State API for token caching");
|
|
5237
|
+
this.state = await import_aio_sdk12.State.init();
|
|
5238
|
+
} catch (error) {
|
|
5239
|
+
this.customLogger.error(`Failed to initialize State API: ${error.message}`);
|
|
5240
|
+
this.state = null;
|
|
5241
|
+
}
|
|
5242
|
+
}
|
|
5243
|
+
return this.state;
|
|
5244
|
+
}
|
|
5245
|
+
};
|
|
5246
|
+
__name(_GenerateImsToken, "GenerateImsToken");
|
|
5247
|
+
var GenerateImsToken = _GenerateImsToken;
|
|
5248
|
+
var generate_ims_token_default = GenerateImsToken;
|
|
5249
|
+
|
|
4905
5250
|
// src/commerce/adobe-commerce-client/ims-connection/index.ts
|
|
4906
|
-
var import_aio_sdk11 = require("@adobe/aio-sdk");
|
|
4907
5251
|
var _ImsConnection = class _ImsConnection {
|
|
4908
5252
|
/**
|
|
4909
5253
|
* @param clientId
|
|
@@ -4913,38 +5257,35 @@ var _ImsConnection = class _ImsConnection {
|
|
|
4913
5257
|
* @param imsOrgId
|
|
4914
5258
|
* @param scopes
|
|
4915
5259
|
* @param logger
|
|
4916
|
-
* @param currentContext
|
|
4917
5260
|
*/
|
|
4918
|
-
constructor(clientId, clientSecret, technicalAccountId, technicalAccountEmail, imsOrgId, scopes, logger = null
|
|
5261
|
+
constructor(clientId, clientSecret, technicalAccountId, technicalAccountEmail, imsOrgId, scopes, logger = null) {
|
|
4919
5262
|
this.clientId = clientId;
|
|
4920
5263
|
this.clientSecret = clientSecret;
|
|
4921
5264
|
this.technicalAccountId = technicalAccountId;
|
|
4922
5265
|
this.technicalAccountEmail = technicalAccountEmail;
|
|
4923
5266
|
this.imsOrgId = imsOrgId;
|
|
4924
5267
|
this.scopes = scopes;
|
|
4925
|
-
this.
|
|
4926
|
-
if (logger === null) {
|
|
4927
|
-
logger = import_aio_sdk11.Core.Logger(currentContext, {
|
|
4928
|
-
level: "debug"
|
|
4929
|
-
});
|
|
4930
|
-
}
|
|
4931
|
-
this.logger = logger;
|
|
5268
|
+
this.customLogger = new custom_logger_default(logger);
|
|
4932
5269
|
}
|
|
4933
5270
|
/**
|
|
4934
5271
|
* @param commerceGot
|
|
4935
5272
|
*/
|
|
4936
5273
|
async extend(commerceGot) {
|
|
4937
|
-
this.
|
|
4938
|
-
const
|
|
5274
|
+
this.customLogger.info("Using Commerce client with IMS authentication");
|
|
5275
|
+
const tokenGenerator = new generate_ims_token_default(
|
|
4939
5276
|
this.clientId,
|
|
4940
5277
|
this.clientSecret,
|
|
4941
5278
|
this.technicalAccountId,
|
|
4942
5279
|
this.technicalAccountEmail,
|
|
4943
5280
|
this.imsOrgId,
|
|
4944
5281
|
this.scopes,
|
|
4945
|
-
this.
|
|
5282
|
+
this.customLogger.getLogger()
|
|
4946
5283
|
);
|
|
4947
|
-
|
|
5284
|
+
const token = await tokenGenerator.execute();
|
|
5285
|
+
if (token === null) {
|
|
5286
|
+
throw new Error("Failed to generate or retrieve IMS token");
|
|
5287
|
+
}
|
|
5288
|
+
this.customLogger.info(`IMS token being extended to header: ${token.substring(0, 10)}...`);
|
|
4948
5289
|
return commerceGot.extend({
|
|
4949
5290
|
headers: {
|
|
4950
5291
|
Authorization: `Bearer ${token}`
|
|
@@ -4955,8 +5296,169 @@ var _ImsConnection = class _ImsConnection {
|
|
|
4955
5296
|
__name(_ImsConnection, "ImsConnection");
|
|
4956
5297
|
var ImsConnection = _ImsConnection;
|
|
4957
5298
|
var ims_connection_default = ImsConnection;
|
|
5299
|
+
|
|
5300
|
+
// src/experience/admin-ui-sdk/index.ts
|
|
5301
|
+
var _AdminUiSdk = class _AdminUiSdk {
|
|
5302
|
+
/**
|
|
5303
|
+
* Creates a new AdminUiSdk instance
|
|
5304
|
+
* @param extensionId - Unique identifier for the extension
|
|
5305
|
+
* @throws {Error} If extensionId is empty or invalid
|
|
5306
|
+
*/
|
|
5307
|
+
constructor(extensionId) {
|
|
5308
|
+
this.menuItems = [];
|
|
5309
|
+
if (!extensionId?.trim()) {
|
|
5310
|
+
throw new Error("Extension ID is required and cannot be empty");
|
|
5311
|
+
}
|
|
5312
|
+
const trimmedId = extensionId.trim();
|
|
5313
|
+
if (!this.isValidExtensionId(trimmedId)) {
|
|
5314
|
+
throw new Error(
|
|
5315
|
+
"Extension ID must be alphanumeric with underscores only (no spaces, hyphens, or special characters)"
|
|
5316
|
+
);
|
|
5317
|
+
}
|
|
5318
|
+
this.extensionId = trimmedId;
|
|
5319
|
+
}
|
|
5320
|
+
/**
|
|
5321
|
+
* Validates that an extension ID contains only alphanumeric characters and underscores
|
|
5322
|
+
* @param id - The extension ID to validate
|
|
5323
|
+
* @returns true if valid, false otherwise
|
|
5324
|
+
*/
|
|
5325
|
+
isValidExtensionId(id) {
|
|
5326
|
+
return /^[a-zA-Z0-9_]+$/.test(id);
|
|
5327
|
+
}
|
|
5328
|
+
/**
|
|
5329
|
+
* Validates that a menu ID is valid (can contain :: separator for namespacing)
|
|
5330
|
+
* @param id - The menu ID to validate
|
|
5331
|
+
* @returns true if valid, false otherwise
|
|
5332
|
+
*/
|
|
5333
|
+
isValidMenuId(id) {
|
|
5334
|
+
return /^[a-zA-Z0-9_:]+$/.test(id);
|
|
5335
|
+
}
|
|
5336
|
+
/**
|
|
5337
|
+
* Adds a menu item to the extension
|
|
5338
|
+
* @param id - Full identifier for the menu item (e.g., 'extensionId::menuItem')
|
|
5339
|
+
* @param title - Display title for the menu item
|
|
5340
|
+
* @param sortOrder - Sort order for menu positioning
|
|
5341
|
+
* @param parent - Parent menu identifier (optional, full ID like 'extensionId::parent')
|
|
5342
|
+
* @throws {Error} If parameters are invalid or ID already exists
|
|
5343
|
+
*/
|
|
5344
|
+
addMenuItem(id, title, sortOrder, parent) {
|
|
5345
|
+
if (!id?.trim()) {
|
|
5346
|
+
throw new Error("Menu item ID is required and cannot be empty");
|
|
5347
|
+
}
|
|
5348
|
+
if (!this.isValidMenuId(id.trim())) {
|
|
5349
|
+
throw new Error(
|
|
5350
|
+
"Menu item ID must be alphanumeric with underscores and colons only (no spaces, hyphens, or other special characters)"
|
|
5351
|
+
);
|
|
5352
|
+
}
|
|
5353
|
+
if (!title?.trim()) {
|
|
5354
|
+
throw new Error("Menu item title is required and cannot be empty");
|
|
5355
|
+
}
|
|
5356
|
+
if (parent !== void 0 && !parent?.trim()) {
|
|
5357
|
+
throw new Error("Menu item parent cannot be empty if provided");
|
|
5358
|
+
}
|
|
5359
|
+
if (parent !== void 0 && !this.isValidMenuId(parent.trim())) {
|
|
5360
|
+
throw new Error(
|
|
5361
|
+
"Menu item parent must be alphanumeric with underscores and colons only (no spaces, hyphens, or other special characters)"
|
|
5362
|
+
);
|
|
5363
|
+
}
|
|
5364
|
+
if (typeof sortOrder !== "number" || sortOrder < 0) {
|
|
5365
|
+
throw new Error("Menu item sortOrder must be a non-negative number");
|
|
5366
|
+
}
|
|
5367
|
+
const trimmedId = id.trim();
|
|
5368
|
+
if (this.menuItems.some((item) => item.id === trimmedId)) {
|
|
5369
|
+
throw new Error(`Menu item with ID '${trimmedId}' already exists`);
|
|
5370
|
+
}
|
|
5371
|
+
const menuItem = {
|
|
5372
|
+
id: trimmedId,
|
|
5373
|
+
title: title.trim(),
|
|
5374
|
+
sortOrder
|
|
5375
|
+
};
|
|
5376
|
+
if (parent?.trim()) {
|
|
5377
|
+
menuItem.parent = parent.trim();
|
|
5378
|
+
}
|
|
5379
|
+
this.menuItems.push(menuItem);
|
|
5380
|
+
}
|
|
5381
|
+
/**
|
|
5382
|
+
* Adds a menu section to the extension
|
|
5383
|
+
* @param id - Full identifier for the menu section (e.g., 'extensionId::section')
|
|
5384
|
+
* @param title - Display title for the menu section
|
|
5385
|
+
* @param sortOrder - Sort order for section positioning
|
|
5386
|
+
* @param parent - Parent menu identifier (optional, full ID like 'Magento_Backend::system')
|
|
5387
|
+
* @throws {Error} If parameters are invalid or ID already exists
|
|
5388
|
+
*/
|
|
5389
|
+
addMenuSection(id, title, sortOrder, parent) {
|
|
5390
|
+
if (!id?.trim()) {
|
|
5391
|
+
throw new Error("Menu section ID is required and cannot be empty");
|
|
5392
|
+
}
|
|
5393
|
+
if (!this.isValidMenuId(id.trim())) {
|
|
5394
|
+
throw new Error(
|
|
5395
|
+
"Menu section ID must be alphanumeric with underscores and colons only (no spaces, hyphens, or other special characters)"
|
|
5396
|
+
);
|
|
5397
|
+
}
|
|
5398
|
+
if (!title?.trim()) {
|
|
5399
|
+
throw new Error("Menu section title is required and cannot be empty");
|
|
5400
|
+
}
|
|
5401
|
+
if (parent !== void 0 && !parent?.trim()) {
|
|
5402
|
+
throw new Error("Menu section parent cannot be empty if provided");
|
|
5403
|
+
}
|
|
5404
|
+
if (parent !== void 0 && !this.isValidMenuId(parent.trim())) {
|
|
5405
|
+
throw new Error(
|
|
5406
|
+
"Menu section parent must be alphanumeric with underscores and colons only (no spaces, hyphens, or other special characters)"
|
|
5407
|
+
);
|
|
5408
|
+
}
|
|
5409
|
+
if (typeof sortOrder !== "number" || sortOrder < 0) {
|
|
5410
|
+
throw new Error("Menu section sortOrder must be a non-negative number");
|
|
5411
|
+
}
|
|
5412
|
+
const trimmedId = id.trim();
|
|
5413
|
+
if (this.menuItems.some((item) => item.id === trimmedId)) {
|
|
5414
|
+
throw new Error(`Menu item with ID '${trimmedId}' already exists`);
|
|
5415
|
+
}
|
|
5416
|
+
const menuSection = {
|
|
5417
|
+
id: trimmedId,
|
|
5418
|
+
title: title.trim(),
|
|
5419
|
+
sortOrder,
|
|
5420
|
+
isSection: true
|
|
5421
|
+
};
|
|
5422
|
+
if (parent?.trim()) {
|
|
5423
|
+
menuSection.parent = parent.trim();
|
|
5424
|
+
}
|
|
5425
|
+
this.menuItems.push(menuSection);
|
|
5426
|
+
}
|
|
5427
|
+
/**
|
|
5428
|
+
* Sets the page title for the extension
|
|
5429
|
+
* @param title - The page title
|
|
5430
|
+
* @throws {Error} If title is empty or invalid
|
|
5431
|
+
*/
|
|
5432
|
+
addPage(title) {
|
|
5433
|
+
if (!title?.trim()) {
|
|
5434
|
+
throw new Error("Page title is required and cannot be empty");
|
|
5435
|
+
}
|
|
5436
|
+
this.pageTitle = title.trim();
|
|
5437
|
+
}
|
|
5438
|
+
/**
|
|
5439
|
+
* Gets the complete registration object for the extension
|
|
5440
|
+
* @returns The registration object with optional menu items and page configuration
|
|
5441
|
+
*/
|
|
5442
|
+
getRegistration() {
|
|
5443
|
+
const registration = {};
|
|
5444
|
+
if (this.menuItems.length > 0) {
|
|
5445
|
+
registration.menuItems = [...this.menuItems];
|
|
5446
|
+
}
|
|
5447
|
+
if (this.pageTitle) {
|
|
5448
|
+
registration.page = {
|
|
5449
|
+
title: this.pageTitle
|
|
5450
|
+
};
|
|
5451
|
+
}
|
|
5452
|
+
return {
|
|
5453
|
+
registration
|
|
5454
|
+
};
|
|
5455
|
+
}
|
|
5456
|
+
};
|
|
5457
|
+
__name(_AdminUiSdk, "AdminUiSdk");
|
|
5458
|
+
var AdminUiSdk = _AdminUiSdk;
|
|
4958
5459
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4959
5460
|
0 && (module.exports = {
|
|
5461
|
+
AdminUiSdk,
|
|
4960
5462
|
AdobeAuth,
|
|
4961
5463
|
AdobeCommerceClient,
|
|
4962
5464
|
BasicAuthConnection,
|
|
@@ -4980,6 +5482,7 @@ var ims_connection_default = ImsConnection;
|
|
|
4980
5482
|
OpenwhiskAction,
|
|
4981
5483
|
Parameters,
|
|
4982
5484
|
ProviderManager,
|
|
5485
|
+
PublishEvent,
|
|
4983
5486
|
RegistrationManager,
|
|
4984
5487
|
RestClient,
|
|
4985
5488
|
RuntimeAction,
|